Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e1c6e13
[Enhancement #425] Add interfaces for basic entity graph support.
ledsoft Mar 2, 2026
2ebe40e
[Enhancement #425] Implementing entity graph model (WIP).
ledsoft Mar 2, 2026
b580b71
[Enhancement #425] Extract entity describing query logic into a separ…
ledsoft Mar 18, 2026
386aabe
[Enhancement #425] Recursively build SPARQL patterns from fetch graph.
ledsoft Mar 18, 2026
6bc8907
[Enhancement #425] Reorder generated triple patterns - put OPTIONALs …
ledsoft Mar 18, 2026
39d8102
[Enhancement #425] Allow creating an EntityGraph via EM and pass it t…
ledsoft Mar 18, 2026
28ed293
[Enhancement #425] Use fetch graph to map query results to axioms.
ledsoft Mar 24, 2026
57ca270
[Enhancement #425] Support extracting axioms for multiple entities fr…
ledsoft Mar 25, 2026
d544288
[Enhancement #425] Pass fetch graph to entity loading from axioms.
ledsoft Mar 27, 2026
4175022
[Enhancement #425] Refactor axiom-based entity loading API.
ledsoft Mar 27, 2026
ba1daa1
[Enhancement #425] Minor simplification of ObjectOntologyMapperImpl.
ledsoft Mar 31, 2026
550fe3c
[Enhancement #425] Support loading entity graph from axioms by keepin…
ledsoft Mar 31, 2026
136ba53
[Enhancement #425] Pass fetch graph to entity construction.
ledsoft Apr 9, 2026
4073d0c
[Enhancement #425] Use fetch graph when constructing entities.
ledsoft Apr 9, 2026
b72be05
[Enhancement #425] Add some integration tests for the fetch graph-bas…
ledsoft Apr 9, 2026
e122072
[Enhancement #425] Use optimizer whenever fetch graph is provided to …
ledsoft Apr 10, 2026
dcd6cfe
[Enhancement #425] Add some integration tests.
ledsoft Apr 10, 2026
f2d5e5a
[Enhancement #425] Allow QueryResultLoader to access relevant data fr…
ledsoft Apr 16, 2026
1fe3bcc
[Enhancement #425] Use GROUP_CONCAT to prevent result row blowup for …
ledsoft Apr 17, 2026
e323bcc
[Enhancement #425] Bind type in query optimizer when entity type has …
ledsoft Apr 21, 2026
060d0b9
More robust lazy state resolution.
ledsoft Apr 22, 2026
a0bfc0f
Validate integrity constraints only for loaded attributes.
ledsoft Apr 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions jopa-api/src/main/java/cz/cvut/kbss/jopa/model/AttributeNode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cz.cvut.kbss.jopa.model;

import java.util.Map;

/**
* Represents an attribute node of an entity graph.
*
* @param <T> The type of the attribute
*/
public interface AttributeNode<T> {

/**
* Gets the name of the attribute corresponding to the attribute node.
*
* @return name of the attribute
*/
String getAttributeName();

/**
* Return the map of subgraphs associated with this attribute node.
*
* @return Map of subgraphs associated with this attribute node or empty Map if none have been defined
*/
Map<Class, Subgraph> getSubgraphs();
}
108 changes: 108 additions & 0 deletions jopa-api/src/main/java/cz/cvut/kbss/jopa/model/EntityGraph.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package cz.cvut.kbss.jopa.model;

import cz.cvut.kbss.jopa.model.metamodel.Attribute;

import java.util.List;

/**
* This type represents the root of an entity graph that will be used as a template to define the attribute nodes and
* boundaries of a graph of entities and entity relationships.
* <p>
* The root must be an entity type.
* <p>
* The methods to add subgraphs implicitly create the corresponding attribute nodes as well; such attribute nodes should
* not be redundantly specified.
*
* @param <T> The type of the root entity
*/
public interface EntityGraph<T> {

/**
* Adds one or more attribute nodes to the entity graph.
*
* @param attribute Attribute to add
* @throws IllegalStateException If this {@code EntityGraph} has been statically defined
*/
void addAttributeNodes(Attribute<T, ?>... attribute);

/**
* Adds one or more attribute nodes to the entity graph.
*
* @param attributeName Name of the attribute to add
* @throws IllegalStateException If this {@code EntityGraph} has been statically defined
* @throws IllegalArgumentException If the attribute is not an attribute of this managed type
*/
void addAttributeNodes(String... attributeName);

/**
* Adds a node to the graph that corresponds to a managed type.
* <p>
* This allows for construction of multi-node entity graphs that include related managed types.
*
* @param attribute Attribute to add
* @param <X> Attribute type
* @return Subgraph for the attribute
* @throws IllegalStateException If this {@code EntityGraph} has been statically defined
* @throws IllegalArgumentException If the attribute's target type is not a managed type
*/
<X> Subgraph<X> addSubgraph(Attribute<T, X> attribute);

/**
* Adds a node to the graph that corresponds to a managed type.
* <p>
* This allows for construction of multi-node entity graphs that include related managed types.
*
* @param attributeName Name of the attribute to add
* @param <X> Attribute type
* @return Subgraph for the attribute
* @throws IllegalStateException If this {@code EntityGraph} has been statically defined
* @throws IllegalArgumentException If the attribute is not an attribute of this managed type
* @throws IllegalArgumentException If the attribute's target type is not a managed type
*/
<X> Subgraph<X> addSubgraph(String attributeName);

/**
* Adds a node to the graph that corresponds to a managed type with inheritance.
* <p>
* This allows for multiple subclass subgraphs to be defined for this node of the entity graph. Subclass subgraphs
* will automatically include the specified attributes of superclass subgraphs.
*
* @param attribute Attribute to add
* @param cls Entity subclass
* @param <X> Attribute type
* @return Subgraph for the attribute
* @throws IllegalStateException If this {@code EntityGraph} has been statically defined
* @throws IllegalArgumentException If the attribute's target type is not a managed type
*/
<X> Subgraph<? extends X> addSubgraph(Attribute<T, X> attribute, Class<? extends X> cls);

/**
* Add additional attributes to this entity graph that correspond to attributes of subclasses of this EntityGraph's
* entity type.
* <p>
* Subclass subgraphs will automatically include the specified attributes of superclass subgraphs.
*
* @param cls Entity subclass
* @return Subgraph for the subclass
* @throws IllegalStateException If this {@code EntityGraph} has been statically defined
* @throws IllegalArgumentException If the type is not a managed type
*/
Subgraph<? extends T> addSubclassSubgraph(Class<? extends T> cls);

/**
* Gets the attribute nodes corresponding to the attributes of this managed type that are included in the subgraph.
*
* @return List of attribute nodes included in the subgraph or empty list if none have been defined
*/
List<AttributeNode<?>> getAttributeNodes();

/**
* Gets the name of a named EntityGraph (an entity graph defined by means of the NamedEntityGraph annotation, or
* added by means of the addNamedEntityGraph method).
* <p>
* Returns null if the EntityGraph is not a named EntityGraph.
*
* @return Entity graph name, {@code null} if it is not named
*/
String getName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,15 @@ public interface EntityManager extends AutoCloseable {
*/
Query createNativeQuery(String sparqlString, String resultSetMapping);

/**
* Returns a mutable {@link EntityGraph} that can be used to dynamically create an entity graph.
*
* @param rootType Entity class
* @param <T> Root entity class type
* @return Entity graph
*/
<T> EntityGraph<T> createEntityGraph(Class<T> rootType);

/**
* Return an object of the specified type to allow access to the provider-specific API. If the provider's
* EntityManager implementation does not support the specified class, the {@link OWLPersistenceException} is
Expand Down
88 changes: 88 additions & 0 deletions jopa-api/src/main/java/cz/cvut/kbss/jopa/model/Subgraph.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package cz.cvut.kbss.jopa.model;

import cz.cvut.kbss.jopa.model.metamodel.Attribute;

import java.util.List;

/**
* This type represents a subgraph for an attribute node that corresponds to a Managed Type.
* <p>
* Using this class, an entity subgraph can be embedded within an EntityGraph.
*
* @param <T> The type of the attribute
*/
public interface Subgraph<T> {

/**
* Adds one or more attribute nodes to the entity graph.
*
* @param attribute Attribute to add
* @throws IllegalStateException If this {@code EntityGraph} has been statically defined
*/
void addAttributeNodes(Attribute<T, ?>... attribute);

/**
* Adds one or more attribute nodes to the entity graph.
*
* @param attributeName Name of the attribute to add
* @throws IllegalStateException If this {@code EntityGraph} has been statically defined
* @throws IllegalArgumentException If the attribute is not an attribute of this managed type
*/
void addAttributeNodes(String... attributeName);

/**
* Adds a node to the graph that corresponds to a managed type.
* <p>
* This allows for construction of multi-node entity graphs that include related managed types.
*
* @param attribute Attribute to add
* @param <X> Attribute type
* @return Subgraph for the attribute
* @throws IllegalStateException If this {@code EntityGraph} has been statically defined
* @throws IllegalArgumentException If the attribute's target type is not a managed type
*/
<X> Subgraph<X> addSubgraph(Attribute<T, X> attribute);

/**
* Adds a node to the graph that corresponds to a managed type.
* <p>
* This allows for construction of multi-node entity graphs that include related managed types.
*
* @param attributeName Name of the attribute to add
* @param <X> Attribute type
* @return Subgraph for the attribute
* @throws IllegalStateException If this {@code EntityGraph} has been statically defined
* @throws IllegalArgumentException If the attribute is not an attribute of this managed type
* @throws IllegalArgumentException If the attribute's target type is not a managed type
*/
<X> Subgraph<X> addSubgraph(String attributeName);

/**
* Adds a node to the graph that corresponds to a managed type with inheritance.
* <p>
* This allows for multiple subclass subgraphs to be defined for this node of the entity graph. Subclass subgraphs
* will automatically include the specified attributes of superclass subgraphs.
*
* @param attribute Attribute to add
* @param cls Entity subclass
* @param <X> Attribute type
* @return Subgraph for the attribute
* @throws IllegalStateException If this {@code EntityGraph} has been statically defined
* @throws IllegalArgumentException If the attribute's target type is not a managed type
*/
<X> Subgraph<? extends X> addSubgraph(Attribute<T, X> attribute, Class<? extends X> cls);

/**
* Gets the attribute nodes corresponding to the attributes of this managed type that are included in the subgraph.
*
* @return List of attribute nodes included in the subgraph or empty list if none have been defined
*/
List<AttributeNode<?>> getAttributeNodes();

/**
* Gets the type for which this subgraph was defined.
*
* @return managed type referenced by the subgraph
*/
Class<T> getClassType();
}
20 changes: 2 additions & 18 deletions jopa-impl/src/main/java/cz/cvut/kbss/jopa/model/AbstractQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,9 @@
import cz.cvut.kbss.jopa.model.query.Query;
import cz.cvut.kbss.jopa.query.QueryHolder;
import cz.cvut.kbss.jopa.sessions.ConnectionWrapper;
import cz.cvut.kbss.jopa.utils.ThrowingConsumer;
import cz.cvut.kbss.ontodriver.ResultSet;
import cz.cvut.kbss.ontodriver.Statement;
import cz.cvut.kbss.ontodriver.exception.OntoDriverException;
import cz.cvut.kbss.ontodriver.iteration.ResultRow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -121,7 +119,7 @@ public void executeUpdate() {
}
}

private Statement initQueryStatement() {
Statement initQueryStatement() {
final Statement stmt = connection.createStatement();
applyQueryHints(stmt);
logQuery();
Expand Down Expand Up @@ -265,28 +263,14 @@ void checkNumericParameter(int param, String name) {
}
}

/**
* Executes the query and lets the specified consumer deal with each row in the result set.
*
* @param consumer Called for every row in the result set
* @throws OntoDriverException When something goes wrong during query evaluation or result set processing
*/
void executeQuery(ThrowingConsumer<ResultRow, OntoDriverException> consumer) throws OntoDriverException {
try (final Statement stmt = initQueryStatement()) {
final ResultSet rs = stmt.executeQuery(query.assembleQuery());
for (ResultRow row : rs) {
consumer.accept(row);
}
}
}

private void applyQueryHints(Statement statement) {
hints.forEach((hint, value) -> QueryHintsHandler.apply(hint, value, this, statement));
}

<R> Stream<R> executeQueryForStream(QueryResultLoader<R> resultLoader) throws OntoDriverException {
final Statement stmt = initQueryStatement();
final ResultSet rs = stmt.executeQuery(query.assembleQuery());
resultLoader.init(rs);
final Runnable closeHandler = () -> {
try {
stmt.close();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package cz.cvut.kbss.jopa.model;

import cz.cvut.kbss.jopa.model.metamodel.Attribute;

import java.util.HashMap;
import java.util.Map;

public class AttributeNodeImpl<X> implements AttributeNode<X> {

private final Attribute<?, X> attribute;

private final Map<Class, Subgraph> subgraphs = new HashMap<>();

public AttributeNodeImpl(Attribute<?, X> attribute) {
this.attribute = attribute;
}

public Attribute<?, X> getAttribute() {
return attribute;
}

@Override
public String getAttributeName() {
return attribute.getName();
}

@Override
public Map<Class, Subgraph> getSubgraphs() {
return subgraphs;
}

void addSubgraph(EntityGraphImpl<?> graph) {
subgraphs.put(graph.getClassType(), graph);
}

@Override
public String toString() {
return attribute.toString();
}
}
Loading