diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index bb2579eec8..de68fe3e93 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -244,6 +244,7 @@ import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.Fetch; import org.hibernate.sql.results.graph.Fetchable; +import org.hibernate.sql.results.graph.embeddable.EmbeddableResultGraphNode; import org.hibernate.sql.results.graph.entity.internal.EntityResultImpl; import org.hibernate.sql.results.internal.SqlSelectionImpl; import org.hibernate.stat.spi.StatisticsImplementor; @@ -1867,10 +1868,15 @@ public abstract class AbstractEntityPersister FetchTiming fetchTiming = fetchable.getMappedFetchOptions().getTiming(); final boolean selectable; if ( fetchable instanceof AttributeMapping ) { - final int propertyNumber = ( (AttributeMapping) fetchable ).getStateArrayPosition(); - final int tableNumber = getSubclassPropertyTableNumber( propertyNumber ); - selectable = !isSubclassTableSequentialSelect( tableNumber ) - && propertySelectable[propertyNumber]; + if ( fetchParent instanceof EmbeddableResultGraphNode && ( (EmbeddableResultGraphNode) fetchParent ).getReferencedMappingContainer() == getIdentifierMapping() ) { + selectable = true; + } + else { + final int propertyNumber = ( (AttributeMapping) fetchable ).getStateArrayPosition(); + final int tableNumber = getSubclassPropertyTableNumber( propertyNumber ); + selectable = !isSubclassTableSequentialSelect( tableNumber ) + && propertySelectable[propertyNumber]; + } } else { selectable = true; diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/Builders.java b/hibernate-core/src/main/java/org/hibernate/query/results/Builders.java index 043e197f7c..e74faff98a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/Builders.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/Builders.java @@ -257,7 +257,7 @@ public class Builders { DomainResultCreationState creationState) { if ( fetchable instanceof BasicValuedModelPart ) { final BasicValuedModelPart basicValuedFetchable = (BasicValuedModelPart) fetchable; - return new ImplicitFetchBuilderBasic( fetchPath, basicValuedFetchable ); + return new ImplicitFetchBuilderBasic( fetchPath, basicValuedFetchable, creationState ); } if ( fetchable instanceof EmbeddableValuedFetchable ) { diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/FetchBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/results/FetchBuilder.java index d54879fa77..42c4902e82 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/FetchBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/FetchBuilder.java @@ -29,7 +29,8 @@ import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata; public interface FetchBuilder { Fetch buildFetch( FetchParent parent, - NavigablePath fetchPath, JdbcValuesMetadata jdbcResultsMetadata, + NavigablePath fetchPath, + JdbcValuesMetadata jdbcResultsMetadata, BiFunction legacyFetchResolver, DomainResultCreationState domainResultCreationState); diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/implicit/ImplicitFetchBuilderBasic.java b/hibernate-core/src/main/java/org/hibernate/query/results/implicit/ImplicitFetchBuilderBasic.java index c69431726f..f2e3fb8b13 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/implicit/ImplicitFetchBuilderBasic.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/implicit/ImplicitFetchBuilderBasic.java @@ -6,7 +6,9 @@ */ package org.hibernate.query.results.implicit; +import java.util.function.BiConsumer; import java.util.function.BiFunction; +import java.util.function.Function; import org.hibernate.engine.FetchTiming; import org.hibernate.metamodel.mapping.BasicValuedModelPart; @@ -27,6 +29,7 @@ import org.hibernate.sql.results.graph.FetchParent; import org.hibernate.sql.results.graph.basic.BasicFetch; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata; +import static org.hibernate.query.results.ResultsHelper.impl; import static org.hibernate.query.results.ResultsHelper.jdbcPositionToValuesArrayPosition; import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey; @@ -36,10 +39,23 @@ import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnRefere public class ImplicitFetchBuilderBasic implements ImplicitFetchBuilder, BasicValuedFetchBuilder { private final NavigablePath fetchPath; private final BasicValuedModelPart fetchable; + private final FetchBuilder fetchBuilder; public ImplicitFetchBuilderBasic(NavigablePath fetchPath, BasicValuedModelPart fetchable) { this.fetchPath = fetchPath; this.fetchable = fetchable; + this.fetchBuilder = null; + } + + public ImplicitFetchBuilderBasic( + NavigablePath fetchPath, + BasicValuedModelPart fetchable, + DomainResultCreationState creationState) { + this.fetchPath = fetchPath; + this.fetchable = fetchable; + final DomainResultCreationStateImpl creationStateImpl = impl( creationState ); + final Function fetchBuilderResolver = creationStateImpl.getCurrentExplicitFetchMementoResolver(); + this.fetchBuilder = fetchBuilderResolver.apply( fetchable.getFetchableName() ); } @Override @@ -54,6 +70,15 @@ public class ImplicitFetchBuilderBasic implements ImplicitFetchBuilder, BasicVal JdbcValuesMetadata jdbcResultsMetadata, BiFunction legacyFetchResolver, DomainResultCreationState domainResultCreationState) { + if ( fetchBuilder != null ) { + return (BasicFetch) fetchBuilder.buildFetch( + parent, + fetchPath, + jdbcResultsMetadata, + legacyFetchResolver, + domainResultCreationState + ); + } final DomainResultCreationStateImpl creationStateImpl = ResultsHelper.impl( domainResultCreationState ); final TableGroup parentTableGroup = creationStateImpl @@ -137,4 +162,11 @@ public class ImplicitFetchBuilderBasic implements ImplicitFetchBuilder, BasicVal result = 31 * result + fetchable.hashCode(); return result; } + + @Override + public void visitFetchBuilders(BiConsumer consumer) { + if ( fetchBuilder != null ) { + consumer.accept( fetchPath.getLocalName(), fetchBuilder ); + } + } }