Fix initialization of empty collections

This commit is contained in:
Andrea Boriero 2020-02-26 14:41:09 +00:00
parent db50e046e2
commit 6eb729003a
2 changed files with 78 additions and 7 deletions

View File

@ -67,11 +67,25 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
return;
}
final PluralAttributeMapping collectionAttributeMapping = getCollectionAttributeMapping();
final CollectionPersister collectionDescriptor = collectionAttributeMapping.getCollectionDescriptor();
final CollectionSemantics collectionSemantics = collectionDescriptor.getCollectionSemantics();
final SharedSessionContractImplementor session = rowProcessingState.getSession();
final PersistenceContext persistenceContext = session.getPersistenceContext();
final CollectionKey collectionKey = resolveCollectionKey( rowProcessingState );
if ( collectionKey == null ) {
collectionInstance = collectionSemantics.instantiateWrapper(
null,
collectionDescriptor,
session
);
collectionInstance.initializeEmptyCollection( collectionDescriptor );
persistenceContext.addNonLazyCollection( collectionInstance );
}
if ( CollectionLoadingLogger.TRACE_ENABLED ) {
CollectionLoadingLogger.INSTANCE.tracef(
"(%s) Beginning Initializer#resolveInstance for collection : %s",
@ -92,10 +106,6 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
// final LoadingCollectionEntry existingLoadingEntry = rowProcessingState.getJdbcValuesSourceProcessingState()
// .findLoadingCollectionLocally( getCollectionDescriptor(), collectionKey.getKey() );
final PluralAttributeMapping collectionAttributeMapping = getCollectionAttributeMapping();
final CollectionPersister collectionDescriptor = collectionAttributeMapping.getCollectionDescriptor();
final CollectionSemantics collectionSemantics = collectionDescriptor.getCollectionSemantics();
if ( existingLoadingEntry != null ) {
collectionInstance = existingLoadingEntry.getCollectionInstance();

View File

@ -12,13 +12,16 @@ 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.query.NavigablePath;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
import org.hibernate.sql.results.graph.collection.LoadingCollectionEntry;
import org.hibernate.sql.results.graph.Initializer;
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
import org.hibernate.sql.results.graph.collection.LoadingCollectionEntry;
import org.hibernate.sql.results.graph.entity.EntityInitializer;
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
/**
@ -67,12 +70,32 @@ public class DelayedCollectionInitializer implements CollectionInitializer {
@Override
public void resolveInstance(RowProcessingState rowProcessingState) {
final SharedSessionContractImplementor session = rowProcessingState.getSession();
final PersistenceContext persistenceContext = session.getPersistenceContext();
if ( collectionKey != null ) {
final SharedSessionContractImplementor session = rowProcessingState.getSession();
final PersistenceContext persistenceContext = session.getPersistenceContext();
if ( collectionKey != null ) {
EntityInitializer entityInitializer = getEntityInitializer( rowProcessingState );
final Object entityUsingInterceptor = persistenceContext.getEntity( entityInitializer.getEntityKey() );
if ( entityUsingInterceptor != null ) {
return;
}
final Object key = collectionKey.getKey();
final LoadingCollectionEntry loadingEntry = persistenceContext.getLoadContexts()
.findLoadingCollectionEntry( collectionKey );
final PersistentCollection registeredInstance = persistenceContext.getCollection( collectionKey );
final Object key = collectionKey.getKey();
if ( loadingEntry != null ) {
instance = loadingEntry.getCollectionInstance();
return;
}
final LoadingCollectionEntry loadingEntry = persistenceContext.getLoadContexts()
.findLoadingCollectionEntry( collectionKey );
@ -81,6 +104,9 @@ public class DelayedCollectionInitializer implements CollectionInitializer {
return;
}
if ( registeredInstance != null ) {
instance = registeredInstance;
return;
final PersistentCollection existing = persistenceContext.getCollection( collectionKey );
if ( existing != null ) {
@ -88,10 +114,38 @@ public class DelayedCollectionInitializer implements CollectionInitializer {
return;
}
instance = makePersistentCollection( fetchedMapping, key, rowProcessingState );
persistenceContext.addUninitializedCollection(
getInitializingCollectionDescriptor(),
instance,
key
);
}
else {
instance = makePersistentCollection( fetchedMapping, collectionKey, rowProcessingState );
instance.initializeEmptyCollection( getInitializingCollectionDescriptor() );
persistenceContext.addNonLazyCollection( instance );
}
}
private static PersistentCollection makePersistentCollection(
PluralAttributeMapping fetchedMapping,
Object collectionKey,
RowProcessingState rowProcessingState) {
final CollectionPersister collectionDescriptor = fetchedMapping.getCollectionDescriptor();
final CollectionSemantics collectionSemantics = collectionDescriptor.getCollectionSemantics();
final CollectionPersister collectionDescriptor = fetchedMapping.getCollectionDescriptor();
final CollectionSemantics collectionSemantics = collectionDescriptor.getCollectionSemantics();
return collectionSemantics.instantiateWrapper(
collectionKey,
collectionDescriptor,
rowProcessingState.getSession()
);
}
collectionInstance = collectionSemantics.instantiateWrapper(
key,
collectionDescriptor,
@ -108,12 +162,19 @@ public class DelayedCollectionInitializer implements CollectionInitializer {
key
);
private EntityInitializer getEntityInitializer(RowProcessingState rowProcessingState) {
Initializer initializer = rowProcessingState.resolveInitializer( getNavigablePath().getParent() );
while ( !( initializer instanceof EntityInitializer ) ) {
initializer = rowProcessingState.resolveInitializer( initializer.getNavigablePath().getParent() );
if ( collectionSemantics.getCollectionClassification() == CollectionClassification.ARRAY ) {
session.getPersistenceContext().addCollectionHolder( collectionInstance );
}
}
return (EntityInitializer) initializer;
}
@Override
public void initializeInstance(RowProcessingState rowProcessingState) {
}
@ -126,7 +187,7 @@ public class DelayedCollectionInitializer implements CollectionInitializer {
@Override
public void finishUpRow(RowProcessingState rowProcessingState) {
collectionKey = null;
collectionInstance = null;
instance = null;
}
@Override
@ -136,7 +197,7 @@ public class DelayedCollectionInitializer implements CollectionInitializer {
@Override
public PersistentCollection getCollectionInstance() {
return collectionInstance;
return instance;
}
@Override