diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/AbstractEntityInsertAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/AbstractEntityInsertAction.java index 6099dcae6b..9e8a62430d 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/AbstractEntityInsertAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/AbstractEntityInsertAction.java @@ -7,16 +7,22 @@ package org.hibernate.action.internal; import org.hibernate.LockMode; +import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.internal.ForeignKeys; import org.hibernate.engine.internal.NonNullableTransientDependencies; import org.hibernate.engine.internal.Nullability; import org.hibernate.engine.internal.Versioning; import org.hibernate.engine.spi.CachedNaturalIdValueSource; +import org.hibernate.engine.spi.CollectionKey; import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityKey; +import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.Status; import org.hibernate.metamodel.mapping.NaturalIdMapping; +import org.hibernate.metamodel.mapping.PluralAttributeMapping; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.AbstractEntityPersister; import org.hibernate.persister.entity.EntityPersister; /** @@ -132,6 +138,27 @@ public abstract class AbstractEntityInsertAction extends EntityAction { getPersister(), isVersionIncrementDisabled ); + if ( isEarlyInsert() ) { + final SharedSessionContractImplementor session = getSession(); + final PersistenceContext persistenceContext = session.getPersistenceContextInternal(); + Object[] objects = getState(); + for ( int i = 0; i < objects.length; i++ ) { + if ( objects[i] instanceof PersistentCollection ) { + final PersistentCollection persistentCollection = (PersistentCollection) objects[i]; + final CollectionPersister collectionPersister = ( (PluralAttributeMapping) getPersister().getAttributeMapping( i ) ).getCollectionDescriptor(); + final CollectionKey collectionKey = new CollectionKey( + collectionPersister, + ( (AbstractEntityPersister) getPersister() ).getCollectionKey( + collectionPersister, + getInstance(), + persistenceContext.getEntry( getInstance() ), + getSession() + ) + ); + persistenceContext.addCollectionByKey( collectionKey, persistentCollection ); + } + } + } } /** 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 ce879e2459..d4616fec99 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 @@ -1614,7 +1614,7 @@ public abstract class AbstractEntityPersister } - protected Object getCollectionKey( + public Object getCollectionKey( CollectionPersister persister, Object owner, EntityEntry ownerEntry, diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/AbstractCollectionInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/AbstractCollectionInitializer.java index a1aeb8b5f5..8073013809 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/AbstractCollectionInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/AbstractCollectionInitializer.java @@ -6,16 +6,22 @@ */ package org.hibernate.sql.results.graph.collection.internal; +import org.hibernate.collection.spi.CollectionSemantics; import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.CollectionKey; +import org.hibernate.engine.spi.PersistenceContext; +import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.log.LoggingHelper; +import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.mapping.PluralAttributeMapping; +import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.AbstractEntityPersister; import org.hibernate.spi.NavigablePath; import org.hibernate.sql.results.graph.DomainResultAssembler; import org.hibernate.sql.results.graph.FetchParentAccess; import org.hibernate.sql.results.graph.collection.CollectionInitializer; import org.hibernate.sql.results.graph.collection.CollectionLoadingLogger; +import org.hibernate.sql.results.graph.collection.LoadingCollectionEntry; import org.hibernate.sql.results.graph.entity.EntityInitializer; import org.hibernate.sql.results.jdbc.spi.RowProcessingState; @@ -85,6 +91,56 @@ public abstract class AbstractCollectionInitializer implements CollectionInitial } } + protected void resolveInstance(RowProcessingState rowProcessingState, boolean isEager) { + if ( collectionKey != null ) { + final SharedSessionContractImplementor session = rowProcessingState.getSession(); + final PersistenceContext persistenceContext = session.getPersistenceContext(); + + final LoadingCollectionEntry loadingEntry = persistenceContext.getLoadContexts() + .findLoadingCollectionEntry( collectionKey ); + + if ( loadingEntry != null ) { + collectionInstance = loadingEntry.getCollectionInstance(); + return; + } + + final PersistentCollection existing = persistenceContext.getCollection( collectionKey ); + + if ( existing != null ) { + collectionInstance = existing; + return; + } + + final CollectionPersister collectionDescriptor = collectionAttributeMapping.getCollectionDescriptor(); + final CollectionSemantics collectionSemantics = collectionDescriptor.getCollectionSemantics(); + final Object key = collectionKey.getKey(); + + collectionInstance = collectionSemantics.instantiateWrapper( + key, + collectionDescriptor, + session + ); + + parentAccess.registerResolutionListener( + owner -> collectionInstance.setOwner( owner ) + ); + + persistenceContext.addUninitializedCollection( + collectionDescriptor, + collectionInstance, + key + ); + + if ( isEager ) { + persistenceContext.addNonLazyCollection( collectionInstance ); + } + + if ( collectionSemantics.getCollectionClassification() == CollectionClassification.ARRAY ) { + session.getPersistenceContext().addCollectionHolder( collectionInstance ); + } + } + } + protected boolean isAttributeAssignableToConcreteDescriptor() { if ( parentAccess instanceof EntityInitializer ) { final AbstractEntityPersister concreteDescriptor = (AbstractEntityPersister) ( (EntityInitializer) parentAccess ).getConcreteDescriptor(); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/DelayedCollectionInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/DelayedCollectionInitializer.java index b070eeb238..abd6eef506 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/DelayedCollectionInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/DelayedCollectionInitializer.java @@ -6,18 +6,11 @@ */ package org.hibernate.sql.results.graph.collection.internal; -import org.hibernate.collection.spi.CollectionSemantics; -import org.hibernate.collection.spi.PersistentCollection; -import org.hibernate.engine.spi.PersistenceContext; -import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.log.LoggingHelper; -import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.mapping.PluralAttributeMapping; -import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.spi.NavigablePath; import org.hibernate.sql.results.graph.DomainResultAssembler; import org.hibernate.sql.results.graph.FetchParentAccess; -import org.hibernate.sql.results.graph.collection.LoadingCollectionEntry; import org.hibernate.sql.results.jdbc.spi.RowProcessingState; /** @@ -35,49 +28,7 @@ public class DelayedCollectionInitializer extends AbstractCollectionInitializer @Override public void resolveInstance(RowProcessingState rowProcessingState) { - if ( collectionKey != null ) { - final SharedSessionContractImplementor session = rowProcessingState.getSession(); - final PersistenceContext persistenceContext = session.getPersistenceContext(); - - final LoadingCollectionEntry loadingEntry = persistenceContext.getLoadContexts() - .findLoadingCollectionEntry( collectionKey ); - - if ( loadingEntry != null ) { - collectionInstance = loadingEntry.getCollectionInstance(); - return; - } - - final PersistentCollection existing = persistenceContext.getCollection( collectionKey ); - - if ( existing != null ) { - collectionInstance = existing; - return; - } - - final CollectionPersister collectionDescriptor = collectionAttributeMapping.getCollectionDescriptor(); - final CollectionSemantics collectionSemantics = collectionDescriptor.getCollectionSemantics(); - final Object key = collectionKey.getKey(); - - collectionInstance = collectionSemantics.instantiateWrapper( - key, - collectionDescriptor, - session - ); - - parentAccess.registerResolutionListener( - owner -> collectionInstance.setOwner( owner ) - ); - - persistenceContext.addUninitializedCollection( - collectionDescriptor, - collectionInstance, - key - ); - - if ( collectionSemantics.getCollectionClassification() == CollectionClassification.ARRAY ) { - session.getPersistenceContext().addCollectionHolder( collectionInstance ); - } - } + resolveInstance( rowProcessingState, false ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/SelectEagerCollectionInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/SelectEagerCollectionInitializer.java index da1c195a79..fa8e7985c4 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/SelectEagerCollectionInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/SelectEagerCollectionInitializer.java @@ -6,18 +6,11 @@ */ package org.hibernate.sql.results.graph.collection.internal; -import org.hibernate.collection.spi.CollectionSemantics; -import org.hibernate.collection.spi.PersistentCollection; -import org.hibernate.engine.spi.PersistenceContext; -import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.log.LoggingHelper; -import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.mapping.PluralAttributeMapping; -import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.spi.NavigablePath; import org.hibernate.sql.results.graph.DomainResultAssembler; import org.hibernate.sql.results.graph.FetchParentAccess; -import org.hibernate.sql.results.graph.collection.LoadingCollectionEntry; import org.hibernate.sql.results.jdbc.spi.RowProcessingState; /** @@ -35,51 +28,7 @@ public class SelectEagerCollectionInitializer extends AbstractCollectionInitiali @Override public void resolveInstance(RowProcessingState rowProcessingState) { - if ( collectionKey != null ) { - final SharedSessionContractImplementor session = rowProcessingState.getSession(); - final PersistenceContext persistenceContext = session.getPersistenceContext(); - - final LoadingCollectionEntry loadingEntry = persistenceContext.getLoadContexts() - .findLoadingCollectionEntry( collectionKey ); - - if ( loadingEntry != null ) { - collectionInstance = loadingEntry.getCollectionInstance(); - return; - } - - final PersistentCollection existing = persistenceContext.getCollection( collectionKey ); - - if ( existing != null ) { - collectionInstance = existing; - return; - } - - final CollectionPersister collectionDescriptor = collectionAttributeMapping.getCollectionDescriptor(); - final CollectionSemantics collectionSemantics = collectionDescriptor.getCollectionSemantics(); - final Object key = collectionKey.getKey(); - - collectionInstance = collectionSemantics.instantiateWrapper( - key, - collectionDescriptor, - session - ); - - parentAccess.registerResolutionListener( - owner -> collectionInstance.setOwner( owner ) - ); - - persistenceContext.addUninitializedCollection( - collectionDescriptor, - collectionInstance, - key - ); - - persistenceContext.addNonLazyCollection( collectionInstance ); - - if ( collectionSemantics.getCollectionClassification() == CollectionClassification.ARRAY ) { - session.getPersistenceContext().addCollectionHolder( collectionInstance ); - } - } + resolveInstance( rowProcessingState, true ); } @Override