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.FetchParentAccess;
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.graph.collection.LoadingCollectionEntry;
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
@ -106,8 +107,18 @@ public class DelayedCollectionAssembler implements DomainResultAssembler {
@Override
public void resolveInstance(RowProcessingState rowProcessingState) {
if ( collectionKey != null ) {
EntityInitializer entityInitializer = getEntityInitializer( rowProcessingState );
final SharedSessionContractImplementor session = rowProcessingState.getSession();
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()
.findLoadingCollectionEntry( collectionKey );
final PersistentCollection registeredInstance = persistenceContext.getCollection( collectionKey );
@ -122,16 +133,23 @@ public class DelayedCollectionAssembler implements DomainResultAssembler {
return;
}
this.instance = makePersistentCollection( fetchedMapping, collectionKey, rowProcessingState );
persistenceContext.addUninitializedCollection(
getInitializingCollectionDescriptor(),
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(
PluralAttributeMapping fetchedMapping,
CollectionKey collectionKey,

View File

@ -196,6 +196,11 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
return entityKey.getIdentifier();
}
@Override
public EntityKey getEntityKey() {
return entityKey;
}
@Override
public Object getParentKey() {
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
// initializer is already loading the entity
final LoadingEntityEntry existingLoadingEntry = session.getPersistenceContext()
final LoadingEntityEntry existingLoadingEntry = persistenceContext
.getLoadContexts()
.findLoadingEntityEntry( entityKey );
@ -390,7 +406,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
if ( entityInstance == null ) {
// 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 ) {
this.entityInstance = entity;
}
@ -432,6 +448,13 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
return;
}
final SharedSessionContractImplementor session = rowProcessingState.getJdbcValuesSourceProcessingState().getSession();
final PersistenceContext persistenceContext = session.getPersistenceContext();
if ( persistenceContext.getEntity( entityKey ) != null ) {
return;
}
final Serializable entityIdentifier = entityKey.getIdentifier();
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 ?
if ( persistenceContext.containsEntity( entityKey ) ) {

View File

@ -6,6 +6,7 @@
*/
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.Initializer;
import org.hibernate.metamodel.mapping.ModelPart;
@ -61,4 +62,6 @@ public interface EntityInitializer extends Initializer, FetchParentAccess {
}
return entityInstance;
}
EntityKey getEntityKey();
}

View File

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

View File

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