EntityInitializer and DelayedCollectoinAssembler see if we have an existing entry in the PC for the EntityKey

This commit is contained in:
Andrea Boriero 2020-02-24 17:58:32 +00:00
parent e61f610e32
commit 94f23dd2d5
5 changed files with 60 additions and 7 deletions

View File

@ -22,6 +22,7 @@ import org.hibernate.sql.results.graph.collection.CollectionInitializer;
import org.hibernate.sql.results.graph.DomainResultAssembler; import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.FetchParentAccess; import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.graph.Initializer; import org.hibernate.sql.results.graph.Initializer;
import org.hibernate.sql.results.graph.entity.EntityInitializer;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions; import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
import org.hibernate.sql.results.graph.collection.LoadingCollectionEntry; import org.hibernate.sql.results.graph.collection.LoadingCollectionEntry;
import org.hibernate.sql.results.jdbc.spi.RowProcessingState; import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
@ -106,8 +107,18 @@ public class DelayedCollectionAssembler implements DomainResultAssembler {
@Override @Override
public void resolveInstance(RowProcessingState rowProcessingState) { public void resolveInstance(RowProcessingState rowProcessingState) {
if ( collectionKey != null ) { if ( collectionKey != null ) {
EntityInitializer entityInitializer = getEntityInitializer( rowProcessingState );
final SharedSessionContractImplementor session = rowProcessingState.getSession(); final SharedSessionContractImplementor session = rowProcessingState.getSession();
final PersistenceContext persistenceContext = session.getPersistenceContext(); final PersistenceContext persistenceContext = session.getPersistenceContext();
final Object entityUsingInterceptor = persistenceContext.getEntity(entityInitializer.getEntityKey() );
if ( entityUsingInterceptor != null ) {
return;
}
final Object key = collectionKey.getKey();
final LoadingCollectionEntry loadingEntry = persistenceContext.getLoadContexts() final LoadingCollectionEntry loadingEntry = persistenceContext.getLoadContexts()
.findLoadingCollectionEntry( collectionKey ); .findLoadingCollectionEntry( collectionKey );
final PersistentCollection registeredInstance = persistenceContext.getCollection( collectionKey ); final PersistentCollection registeredInstance = persistenceContext.getCollection( collectionKey );
@ -122,16 +133,23 @@ public class DelayedCollectionAssembler implements DomainResultAssembler {
return; return;
} }
this.instance = makePersistentCollection( fetchedMapping, collectionKey, rowProcessingState ); this.instance = makePersistentCollection( fetchedMapping, collectionKey, rowProcessingState );
persistenceContext.addUninitializedCollection( persistenceContext.addUninitializedCollection(
getInitializingCollectionDescriptor(), getInitializingCollectionDescriptor(),
instance, instance,
collectionKey.getKey() key
); );
} }
} }
private EntityInitializer getEntityInitializer(RowProcessingState rowProcessingState) {
Initializer initializer = rowProcessingState.resolveInitializer( getNavigablePath().getParent() );
while ( !( initializer instanceof EntityInitializer ) ) {
initializer = rowProcessingState.resolveInitializer( initializer.getNavigablePath().getParent() );
}
return (EntityInitializer) initializer;
}
private static PersistentCollection makePersistentCollection( private static PersistentCollection makePersistentCollection(
PluralAttributeMapping fetchedMapping, PluralAttributeMapping fetchedMapping,
CollectionKey collectionKey, CollectionKey collectionKey,

View File

@ -196,6 +196,11 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
return entityKey.getIdentifier(); return entityKey.getIdentifier();
} }
@Override
public EntityKey getEntityKey() {
return entityKey;
}
@Override @Override
public Object getParentKey() { public Object getParentKey() {
return getKeyValue(); return getKeyValue();
@ -342,12 +347,23 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
); );
} }
final SharedSessionContractImplementor session = rowProcessingState.getJdbcValuesSourceProcessingState().getSession(); final SharedSessionContractImplementor session = rowProcessingState
.getJdbcValuesSourceProcessingState()
.getSession();
final PersistenceContext persistenceContext = session.getPersistenceContext();
final Object existingEntity = persistenceContext.getEntity( entityKey );
if ( existingEntity != null ) {
entityInstance = existingEntity;
return;
}
// look to see if another initializer from a parent load context or an earlier // look to see if another initializer from a parent load context or an earlier
// initializer is already loading the entity // initializer is already loading the entity
final LoadingEntityEntry existingLoadingEntry = session.getPersistenceContext() final LoadingEntityEntry existingLoadingEntry = persistenceContext
.getLoadContexts() .getLoadContexts()
.findLoadingEntityEntry( entityKey ); .findLoadingEntityEntry( entityKey );
@ -390,7 +406,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
if ( entityInstance == null ) { if ( entityInstance == null ) {
// see if it is managed in the Session already // see if it is managed in the Session already
final Object entity = session.getPersistenceContext().getEntity( entityKey ); final Object entity = persistenceContext.getEntity( entityKey );
if ( entity != null ) { if ( entity != null ) {
this.entityInstance = entity; this.entityInstance = entity;
} }
@ -432,6 +448,13 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
return; return;
} }
final SharedSessionContractImplementor session = rowProcessingState.getJdbcValuesSourceProcessingState().getSession();
final PersistenceContext persistenceContext = session.getPersistenceContext();
if ( persistenceContext.getEntity( entityKey ) != null ) {
return;
}
final Serializable entityIdentifier = entityKey.getIdentifier(); final Serializable entityIdentifier = entityKey.getIdentifier();
if ( EntityLoadingLogger.TRACE_ENABLED ) { if ( EntityLoadingLogger.TRACE_ENABLED ) {
@ -441,8 +464,6 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
); );
} }
final SharedSessionContractImplementor session = rowProcessingState.getJdbcValuesSourceProcessingState().getSession();
PersistenceContext persistenceContext = session.getPersistenceContext();
// todo (6.0): do we really need this check ? // todo (6.0): do we really need this check ?
if ( persistenceContext.containsEntity( entityKey ) ) { if ( persistenceContext.containsEntity( entityKey ) ) {

View File

@ -6,6 +6,7 @@
*/ */
package org.hibernate.sql.results.graph.entity; package org.hibernate.sql.results.graph.entity;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.sql.results.graph.FetchParentAccess; import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.graph.Initializer; import org.hibernate.sql.results.graph.Initializer;
import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.ModelPart;
@ -61,4 +62,6 @@ public interface EntityInitializer extends Initializer, FetchParentAccess {
} }
return entityInstance; return entityInstance;
} }
EntityKey getEntityKey();
} }

View File

@ -116,6 +116,11 @@ public class EntityFetchDelayedInitializer extends AbstractFetchParentAccess imp
return entityInstance; return entityInstance;
} }
@Override
public EntityKey getEntityKey() {
throw new NotYetImplementedFor6Exception( getClass() );
}
@Override @Override
public Object getParentKey() { public Object getParentKey() {
throw new NotYetImplementedFor6Exception( getClass() ); throw new NotYetImplementedFor6Exception( getClass() );

View File

@ -9,6 +9,7 @@ package org.hibernate.sql.results.graph.entity.internal;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.HibernateProxy;
@ -100,6 +101,11 @@ public class EntityInitializerSelectFetch extends AbstractFetchParentAccess impl
return entityInstance; return entityInstance;
} }
@Override
public EntityKey getEntityKey() {
throw new NotYetImplementedFor6Exception( getClass() );
}
@Override @Override
public Object getParentKey() { public Object getParentKey() {
throw new NotYetImplementedFor6Exception( getClass() ); throw new NotYetImplementedFor6Exception( getClass() );