diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java index 759e17b829cc..4e17d33a63b4 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java @@ -52,7 +52,7 @@ import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.exec.internal.JdbcParameterImpl; import org.hibernate.sql.results.graph.DomainResult; -import org.hibernate.sql.results.graph.EntityGraphNavigator; +import org.hibernate.sql.results.graph.EntityGraphSemanticTraverser; import org.hibernate.sql.results.graph.Fetch; import org.hibernate.sql.results.graph.FetchParent; import org.hibernate.sql.results.graph.Fetchable; @@ -60,7 +60,7 @@ import org.hibernate.sql.results.graph.collection.internal.CollectionDomainResult; import org.hibernate.sql.results.graph.entity.EntityResultGraphNode; import org.hibernate.sql.results.internal.SqlSelectionImpl; -import org.hibernate.sql.results.internal.StandardEntityGraphNavigatorImpl; +import org.hibernate.sql.results.internal.StandardEntityGraphSemanticTraverserImpl; import org.jboss.logging.Logger; @@ -158,7 +158,7 @@ public static SelectStatement createSubSelectFetchSelect( private final LoadQueryInfluencers loadQueryInfluencers; private final LockOptions lockOptions; private final Consumer jdbcParameterConsumer; - private final EntityGraphNavigator entityGraphNavigator; + private final EntityGraphSemanticTraverser entityGraphSemanticTraverser; private int fetchDepth; private Map orderByFragments; @@ -183,10 +183,10 @@ private LoaderSelectBuilder( if ( loadQueryInfluencers != null && loadQueryInfluencers.getEffectiveEntityGraph() != null && loadQueryInfluencers.getEffectiveEntityGraph().getSemantic() != null ) { - this.entityGraphNavigator = new StandardEntityGraphNavigatorImpl( loadQueryInfluencers.getEffectiveEntityGraph() ); + this.entityGraphSemanticTraverser = new StandardEntityGraphSemanticTraverserImpl( loadQueryInfluencers.getEffectiveEntityGraph() ); } else { - this.entityGraphNavigator = null; + this.entityGraphSemanticTraverser = null; } this.lockOptions = lockOptions != null ? lockOptions : LockOptions.NONE; this.jdbcParameterConsumer = jdbcParameterConsumer; @@ -427,13 +427,13 @@ private BiConsumer createFetchableBiConsumer( FetchTiming fetchTiming = fetchable.getMappedFetchStrategy().getTiming(); boolean joined = fetchable.getMappedFetchStrategy().getStyle() == FetchStyle.JOIN; - EntityGraphNavigator.Navigation navigation = null; + EntityGraphSemanticTraverser.Result result = null; // 'entity graph' takes precedence over 'fetch profile' - if ( entityGraphNavigator != null) { - navigation = entityGraphNavigator.navigate( fetchParent, fetchable, isKeyFetchable ); - fetchTiming = navigation.getFetchStrategy(); - joined = navigation.isJoined(); + if ( entityGraphSemanticTraverser != null) { + result = entityGraphSemanticTraverser.traverse( fetchParent, fetchable, isKeyFetchable ); + fetchTiming = result.getFetchStrategy(); + joined = result.isJoined(); } else if ( loadQueryInfluencers.hasEnabledFetchProfiles() ) { if ( fetchParent instanceof EntityResultGraphNode ) { @@ -491,8 +491,8 @@ else if ( fetchDepth > maximumFetchDepth ) { if ( !( fetchable instanceof BasicValuedModelPart ) ) { fetchDepth--; } - if ( entityGraphNavigator != null ) { - entityGraphNavigator.backtrack( navigation.getPreviousContext() ); + if ( entityGraphSemanticTraverser != null ) { + entityGraphSemanticTraverser.backtrack( result.getPreviousContext() ); } } }; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/StandardSqmSelectTranslator.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/StandardSqmSelectTranslator.java index edf39db328ae..14e2189574bd 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/StandardSqmSelectTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/StandardSqmSelectTranslator.java @@ -61,13 +61,13 @@ import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.DomainResultCreationState; -import org.hibernate.sql.results.graph.EntityGraphNavigator; +import org.hibernate.sql.results.graph.EntityGraphSemanticTraverser; import org.hibernate.sql.results.graph.Fetch; import org.hibernate.sql.results.graph.FetchParent; import org.hibernate.sql.results.graph.Fetchable; import org.hibernate.sql.results.graph.entity.EntityResultGraphNode; import org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiation; -import org.hibernate.sql.results.internal.StandardEntityGraphNavigatorImpl; +import org.hibernate.sql.results.internal.StandardEntityGraphSemanticTraverserImpl; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; /** @@ -85,7 +85,7 @@ public class StandardSqmSelectTranslator // prepare for 10 root selections to avoid list growth in most cases private final List domainResults = CollectionHelper.arrayList( 10 ); - private final EntityGraphNavigator entityGraphNavigator; + private final EntityGraphSemanticTraverser entityGraphSemanticTraverser; private int fetchDepth; @@ -101,10 +101,10 @@ public StandardSqmSelectTranslator( if ( fetchInfluencers != null && fetchInfluencers.getEffectiveEntityGraph() != null && fetchInfluencers.getEffectiveEntityGraph().getSemantic() != null ) { - this.entityGraphNavigator = new StandardEntityGraphNavigatorImpl( fetchInfluencers.getEffectiveEntityGraph() ); + this.entityGraphSemanticTraverser = new StandardEntityGraphSemanticTraverserImpl( fetchInfluencers.getEffectiveEntityGraph() ); } else { - this.entityGraphNavigator = null; + this.entityGraphSemanticTraverser = null; } } @@ -284,7 +284,7 @@ private Fetch buildFetch(NavigablePath fetchablePath, FetchParent fetchParent, F FetchTiming fetchTiming = fetchable.getMappedFetchStrategy().getTiming(); boolean joined = false; - EntityGraphNavigator.Navigation navigation = null; + EntityGraphSemanticTraverser.Result result = null; final SqmAttributeJoin fetchedJoin = getFromClauseIndex().findFetchedJoinByPath( fetchablePath ); @@ -306,10 +306,10 @@ private Fetch buildFetch(NavigablePath fetchablePath, FetchParent fetchParent, F // there was not an explicit fetch in the SQM alias = null; - if ( entityGraphNavigator != null ) { - navigation = entityGraphNavigator.navigate( fetchParent, fetchable, isKeyFetchable ); - fetchTiming = navigation.getFetchStrategy(); - joined = navigation.isJoined(); + if ( entityGraphSemanticTraverser != null ) { + result = entityGraphSemanticTraverser.traverse( fetchParent, fetchable, isKeyFetchable ); + fetchTiming = result.getFetchStrategy(); + joined = result.isJoined(); } else if ( fetchInfluencers.hasEnabledFetchProfiles() ) { if ( fetchParent instanceof EntityResultGraphNode ) { @@ -416,8 +416,8 @@ else if ( fetchDepth > maxDepth ) { ); } finally { - if ( entityGraphNavigator != null && navigation != null ) { - entityGraphNavigator.backtrack( navigation.getPreviousContext() ); + if ( entityGraphSemanticTraverser != null && result != null ) { + entityGraphSemanticTraverser.backtrack( result.getPreviousContext() ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/EntityGraphNavigator.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/EntityGraphSemanticTraverser.java similarity index 56% rename from hibernate-core/src/main/java/org/hibernate/sql/results/graph/EntityGraphNavigator.java rename to hibernate-core/src/main/java/org/hibernate/sql/results/graph/EntityGraphSemanticTraverser.java index cfd7d92d1074..efeaab166456 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/EntityGraphNavigator.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/EntityGraphSemanticTraverser.java @@ -12,23 +12,23 @@ /** * @author Nathan Xu */ -public interface EntityGraphNavigator { +public interface EntityGraphSemanticTraverser { /** - * Pojo class to store the result of applied entity graph navigation, including + * POJO class to store the result of applied entity graph traversal, including *
    - *
  • previous entity graph node so later on navigator can backtrack to it
  • + *
  • previous entity graph node so later on traverser can backtrack to it
  • *
  • whether the new graph node should be eagerly loaded or not
  • *
  • whether the new graph node fetching is joined
  • *
*/ - class Navigation { + class Result { private GraphImplementor previousContext; private FetchTiming fetchTiming; private boolean joined; - public Navigation(GraphImplementor previousContext, FetchTiming fetchTiming, boolean joined) { + public Result(GraphImplementor previousContext, FetchTiming fetchTiming, boolean joined) { this.previousContext = previousContext; this.fetchTiming = fetchTiming; this.joined = joined; @@ -48,22 +48,21 @@ public boolean isJoined() { } /** - * Backtrack to previous entity graph status after the current children navigating has been done. + * Backtrack to previous entity graph status before last travrsal. * Mainly reset the current context entity graph node to the passed method parameter. * - * @param previousContext The stored previous invocation result; should not be null - * @see #navigate(FetchParent, Fetchable, boolean) + * @param previousContext The previous entity graph context node; should not be null + * @see #traverse(FetchParent, Fetchable, boolean) */ void backtrack(GraphImplementor previousContext); /** - * Tries to navigate from parent to child node within entity graph and returns non-null {@code NavigateResult}. + * Tries to traverse from parent to child node within entity graph and returns non-null {@code Result}. * - * @apiNote If applicable, internal state will be mutated. Not thread safe and should be used within single thread. - * @param parent The FetchParent - * @param fetchable The Fetchable + * @param parent The FetchParent or traversal source node + * @param fetchable The Fetchable or traversal destination node * @param exploreKeySubgraph true if only key sub graph is explored; false if key sub graph is excluded - * @return resulting {@link Navigation}; never null + * @return traversal result; never be null */ - Navigation navigate(FetchParent parent, Fetchable fetchable, boolean exploreKeySubgraph); + Result traverse(FetchParent parent, Fetchable fetchable, boolean exploreKeySubgraph); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/StandardEntityGraphNavigatorImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/StandardEntityGraphSemanticTraverserImpl.java similarity index 67% rename from hibernate-core/src/main/java/org/hibernate/sql/results/internal/StandardEntityGraphNavigatorImpl.java rename to hibernate-core/src/main/java/org/hibernate/sql/results/internal/StandardEntityGraphSemanticTraverserImpl.java index cfcf5f092e8e..829d5c3b9253 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/StandardEntityGraphNavigatorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/StandardEntityGraphSemanticTraverserImpl.java @@ -21,7 +21,7 @@ import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.internal.EntityCollectionPart; import org.hibernate.metamodel.model.domain.EntityDomainType; -import org.hibernate.sql.results.graph.EntityGraphNavigator; +import org.hibernate.sql.results.graph.EntityGraphSemanticTraverser; import org.hibernate.sql.results.graph.FetchParent; import org.hibernate.sql.results.graph.Fetchable; import org.hibernate.sql.results.graph.entity.EntityResultGraphNode; @@ -29,12 +29,12 @@ /** * @author Nathan Xu */ -public class StandardEntityGraphNavigatorImpl implements EntityGraphNavigator { +public class StandardEntityGraphSemanticTraverserImpl implements EntityGraphSemanticTraverser { private final GraphSemantic graphSemantic; private GraphImplementor currentGraphContext; - public StandardEntityGraphNavigatorImpl(EffectiveEntityGraph effectiveEntityGraph) { + public StandardEntityGraphSemanticTraverserImpl(EffectiveEntityGraph effectiveEntityGraph) { assert effectiveEntityGraph != null; if ( effectiveEntityGraph.getSemantic() == null ) { throw new IllegalArgumentException( "The graph has not defined semantic: " + effectiveEntityGraph ); @@ -49,52 +49,47 @@ public void backtrack(GraphImplementor previousContext) { } @Override - public Navigation navigate(FetchParent fetchParent, Fetchable fetchable, boolean exploreKeySubgraph) { + public Result traverse(FetchParent fetchParent, Fetchable fetchable, boolean exploreKeySubgraph) { final GraphImplementor previousContextRoot = currentGraphContext; + AttributeNodeImplementor attributeNode = null; + if ( appliesTo( fetchParent ) ) { + attributeNode = currentGraphContext.findAttributeNode( fetchable.getFetchableName() ); + } + + currentGraphContext = null; FetchTiming fetchTiming = null; boolean joined = false; - if ( appliesTo( fetchParent ) ) { - final AttributeNodeImplementor attributeNode = currentGraphContext.findAttributeNode( fetchable.getFetchableName() ); - if ( attributeNode != null ) { - fetchTiming = FetchTiming.IMMEDIATE; - joined = true; - - final Map, SubGraphImplementor> subgraphMap; - final Class subgraphMapKey; - - if ( fetchable instanceof PluralAttributeMapping ) { - PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) fetchable; - - assert exploreKeySubgraph && isJpaMapCollectionType( pluralAttributeMapping ) - || !exploreKeySubgraph && !isJpaMapCollectionType( pluralAttributeMapping ); - - if ( exploreKeySubgraph ) { - subgraphMap = attributeNode.getKeySubGraphMap(); - subgraphMapKey = getEntityCollectionPartJavaClass( pluralAttributeMapping.getIndexDescriptor() ); - } - else { - subgraphMap = attributeNode.getSubGraphMap(); - subgraphMapKey = getEntityCollectionPartJavaClass( pluralAttributeMapping.getElementDescriptor() ); - } + + if ( attributeNode != null ) { + fetchTiming = FetchTiming.IMMEDIATE; + joined = true; + + final Map, SubGraphImplementor> subgraphMap; + final Class subgraphMapKey; + + if ( fetchable instanceof PluralAttributeMapping ) { + PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) fetchable; + + assert exploreKeySubgraph && isJpaMapCollectionType( pluralAttributeMapping ) + || !exploreKeySubgraph && !isJpaMapCollectionType( pluralAttributeMapping ); + + if ( exploreKeySubgraph ) { + subgraphMap = attributeNode.getKeySubGraphMap(); + subgraphMapKey = getEntityCollectionPartJavaClass( pluralAttributeMapping.getIndexDescriptor() ); } else { - assert !exploreKeySubgraph; subgraphMap = attributeNode.getSubGraphMap(); - subgraphMapKey = fetchable.getJavaTypeDescriptor().getJavaType(); - } - if ( subgraphMap != null && subgraphMapKey != null ) { - currentGraphContext = subgraphMap.get( subgraphMapKey ); - } - else { - currentGraphContext = null; + subgraphMapKey = getEntityCollectionPartJavaClass( pluralAttributeMapping.getElementDescriptor() ); } } else { - currentGraphContext = null; + assert !exploreKeySubgraph; + subgraphMap = attributeNode.getSubGraphMap(); + subgraphMapKey = fetchable.getJavaTypeDescriptor().getJavaType(); + } + if ( subgraphMap != null && subgraphMapKey != null ) { + currentGraphContext = subgraphMap.get( subgraphMapKey ); } - } - else { - currentGraphContext = null; } if ( fetchTiming == null ) { if ( graphSemantic == GraphSemantic.FETCH ) { @@ -106,7 +101,7 @@ assert exploreKeySubgraph && isJpaMapCollectionType( pluralAttributeMapping ) joined = fetchable.getMappedFetchStrategy().getStyle() == FetchStyle.JOIN; } } - return new Navigation( previousContextRoot, fetchTiming, joined ); + return new Result( previousContextRoot, fetchTiming, joined ); } private Class getEntityCollectionPartJavaClass(CollectionPart collectionPart) {