diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/AbstractBatchEntitySelectFetchInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/AbstractBatchEntitySelectFetchInitializer.java index 50774c1b64..b64db5840f 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/AbstractBatchEntitySelectFetchInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/AbstractBatchEntitySelectFetchInitializer.java @@ -27,8 +27,9 @@ public abstract class AbstractBatchEntitySelectFetchInitializer extends Abstract private final NavigablePath navigablePath; protected final EntityPersister concreteDescriptor; - protected final DomainResultAssembler identifierAssembler; + protected final DomainResultAssembler identifierAssembler; protected final ToOneAttributeMapping referencedModelPart; + protected final EntityInitializer firstEntityInitializer; protected Object entityInstance; protected EntityKey entityKey; @@ -38,12 +39,13 @@ public abstract class AbstractBatchEntitySelectFetchInitializer extends Abstract ToOneAttributeMapping referencedModelPart, NavigablePath fetchedNavigable, EntityPersister concreteDescriptor, - DomainResultAssembler identifierAssembler) { + DomainResultAssembler identifierAssembler) { this.parentAccess = parentAccess; this.referencedModelPart = referencedModelPart; this.navigablePath = fetchedNavigable; this.concreteDescriptor = concreteDescriptor; this.identifierAssembler = identifierAssembler; + this.firstEntityInitializer = parentAccess.findFirstEntityInitializer(); } public ModelPart getInitializedPart() { @@ -62,9 +64,11 @@ public abstract class AbstractBatchEntitySelectFetchInitializer extends Abstract return; } entityKey = new EntityKey( entityIdentifier, concreteDescriptor ); - addParentInfo(); + rowProcessingState.getSession().getPersistenceContext() .getBatchFetchQueue().addBatchLoadableEntityKey( entityKey ); + + registerResolutionListener(); } @Override @@ -75,7 +79,7 @@ public abstract class AbstractBatchEntitySelectFetchInitializer extends Abstract public void initializeInstance(RowProcessingState rowProcessingState) { } - protected abstract void addParentInfo(); + protected abstract void registerResolutionListener(); @Override public void finishUpRow(RowProcessingState rowProcessingState) { @@ -125,8 +129,8 @@ public abstract class AbstractBatchEntitySelectFetchInitializer extends Abstract ); } - protected static int getPropertyIndex(FetchParentAccess parentAccess, String propertyName) { - return parentAccess.findFirstEntityInitializer().getEntityDescriptor().getPropertyIndex( propertyName ); + protected static int getPropertyIndex(EntityInitializer entityInitializer, String propertyName) { + return entityInitializer.getConcreteDescriptor().getPropertyIndex( propertyName ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntityInsideEmbeddableSelectFetchInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntityInsideEmbeddableSelectFetchInitializer.java index a43b5b13ce..f5f79b237b 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntityInsideEmbeddableSelectFetchInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntityInsideEmbeddableSelectFetchInitializer.java @@ -27,10 +27,8 @@ import org.hibernate.sql.results.graph.entity.EntityInitializer; import org.hibernate.sql.results.jdbc.spi.RowProcessingState; public class BatchEntityInsideEmbeddableSelectFetchInitializer extends AbstractBatchEntitySelectFetchInitializer { - /* - Object[0] will contain the parent EntityKey and Object[1] the parent embeddable instance, - */ - private final Map> toBatchLoad = new HashMap<>(); + private final Map> toBatchLoad = new HashMap<>(); + private final String rootEmbeddablePropertyName; /** * Marker value for batch properties, needed by the EmbeddableInitializer to instantiate the @@ -52,8 +50,14 @@ public class BatchEntityInsideEmbeddableSelectFetchInitializer extends AbstractB ToOneAttributeMapping referencedModelPart, NavigablePath fetchedNavigable, EntityPersister concreteDescriptor, - DomainResultAssembler identifierAssembler) { + DomainResultAssembler identifierAssembler) { super( parentAccess, referencedModelPart, fetchedNavigable, concreteDescriptor, identifierAssembler ); + + rootEmbeddablePropertyName = getRootEmbeddablePropertyName( + firstEntityInitializer, + parentAccess, + referencedModelPart + ); } @Override @@ -66,21 +70,23 @@ public class BatchEntityInsideEmbeddableSelectFetchInitializer extends AbstractB } @Override - protected void addParentInfo() { - final List parents = getBatchInfos(); + protected void registerResolutionListener() { + final List batchParentInfos = getBatchInfos(); + parentAccess.registerResolutionListener( o -> - parents.add( - new Object[] { - parentAccess.findFirstEntityInitializer().getEntityKey(), - o - } - ) + batchParentInfos.add( + new ParentInfo( + firstEntityInitializer.getEntityKey(), + o, + getPropertyIndex( firstEntityInitializer, rootEmbeddablePropertyName ) + ) + ) ); } - private List getBatchInfos() { - List objects = toBatchLoad.get( entityKey ); + private List getBatchInfos() { + List objects = toBatchLoad.get( entityKey ); if ( objects == null ) { objects = new ArrayList<>(); toBatchLoad.put( entityKey, objects ); @@ -88,26 +94,35 @@ public class BatchEntityInsideEmbeddableSelectFetchInitializer extends AbstractB return objects; } + private static class ParentInfo { + private final EntityKey initializerEntityKey; + private final Object parentInstance; + private final int propertyIndex; + + public ParentInfo(EntityKey initializerEntityKey, Object parentInstance, int propertyIndex) { + this.initializerEntityKey = initializerEntityKey; + this.parentInstance = parentInstance; + this.propertyIndex = propertyIndex; + } + } + @Override public void endLoading(ExecutionContext context) { - final EntityInitializer entityInitializer = parentAccess.findFirstEntityInitializer(); - final String rootEmbeddablePropertyName = getRootEmbeddablePropertyName(); - final int rootEmbeddablePropertyIndex = getPropertyIndex( parentAccess, rootEmbeddablePropertyName ); toBatchLoad.forEach( (entityKey, parentInfos) -> { final SharedSessionContractImplementor session = context.getSession(); final Object loadedInstance = loadInstance( entityKey, referencedModelPart, session ); - for ( Object[] parentInfo : parentInfos ) { + for ( ParentInfo parentInfo : parentInfos ) { final PersistenceContext persistenceContext = session.getPersistenceContext(); setInstance( - entityInitializer, + firstEntityInitializer, referencedModelPart, rootEmbeddablePropertyName, - rootEmbeddablePropertyIndex, + parentInfo.propertyIndex, loadedInstance, - parentInfo[1], - (EntityKey) parentInfo[0], - persistenceContext.getEntry( persistenceContext.getEntity( (EntityKey) parentInfo[0] ) ), + parentInfo.parentInstance, + parentInfo.initializerEntityKey, + persistenceContext.getEntry( persistenceContext.getEntity( parentInfo.initializerEntityKey ) ), session ); } @@ -164,8 +179,11 @@ public class BatchEntityInsideEmbeddableSelectFetchInitializer extends AbstractB } } - protected String getRootEmbeddablePropertyName() { - final NavigablePath entityPath = parentAccess.findFirstEntityDescriptorAccess().getNavigablePath(); + protected static String getRootEmbeddablePropertyName( + EntityInitializer firstEntityInitializer, + FetchParentAccess parentAccess, + ToOneAttributeMapping referencedModelPart) { + final NavigablePath entityPath = firstEntityInitializer.getNavigablePath(); NavigablePath navigablePath = parentAccess.getNavigablePath(); if ( navigablePath == entityPath ) { return referencedModelPart.getPartName(); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntitySelectFetchInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntitySelectFetchInitializer.java index 80e03da2c0..93e081e36f 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntitySelectFetchInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntitySelectFetchInitializer.java @@ -24,27 +24,33 @@ import org.hibernate.sql.results.graph.FetchParentAccess; import org.hibernate.sql.results.graph.entity.EntityInitializer; public class BatchEntitySelectFetchInitializer extends AbstractBatchEntitySelectFetchInitializer { - private final Map> toBatchLoad = new HashMap<>(); + private final Map> toBatchLoad = new HashMap<>(); public BatchEntitySelectFetchInitializer( FetchParentAccess parentAccess, ToOneAttributeMapping referencedModelPart, NavigablePath fetchedNavigable, EntityPersister concreteDescriptor, - DomainResultAssembler identifierAssembler) { + DomainResultAssembler identifierAssembler) { super( parentAccess, referencedModelPart, fetchedNavigable, concreteDescriptor, identifierAssembler ); } @Override - protected void addParentInfo() { - final List parents = getBatchInfos(); + protected void registerResolutionListener() { + final List parents = getParentInfos(); parentAccess.registerResolutionListener( - o -> parents.add( o ) + o -> + parents.add( + new ParentInfo( + o, + getPropertyIndex( firstEntityInitializer, referencedModelPart.getPartName() ) + ) + ) ); } - private List getBatchInfos() { - List objects = toBatchLoad.get( entityKey ); + private List getParentInfos() { + List objects = toBatchLoad.get( entityKey ); if ( objects == null ) { objects = new ArrayList<>(); toBatchLoad.put( entityKey, objects ); @@ -52,21 +58,29 @@ public class BatchEntitySelectFetchInitializer extends AbstractBatchEntitySelect return objects; } + private static class ParentInfo { + private final Object parentInstance; + private final int propertyIndex; + + public ParentInfo(Object parentInstance, int propertyIndex) { + this.parentInstance = parentInstance; + this.propertyIndex = propertyIndex; + } + } + @Override public void endLoading(ExecutionContext context) { - final EntityInitializer entityInitializer = parentAccess.findFirstEntityInitializer(); - final String propertyName = referencedModelPart.getPartName(); - final int propertyIndex = getPropertyIndex( parentAccess, propertyName ); toBatchLoad.forEach( (entityKey, parentInfos) -> { final SharedSessionContractImplementor session = context.getSession(); final Object instance = loadInstance( entityKey, referencedModelPart, session ); - for ( Object parentInstance : parentInfos ) { + for ( ParentInfo parentInfo : parentInfos ) { + final Object parentInstance = parentInfo.parentInstance; setInstance( - entityInitializer, + firstEntityInitializer, referencedModelPart, - propertyName, - propertyIndex, + referencedModelPart.getPartName(), + parentInfo.propertyIndex, session, instance, parentInstance,