HHH-15854 Improve CollectionInitializer and EntityDelayedFetchInitializer resolveInstance methods performance when the parent entity is initialized
This commit is contained in:
parent
312d7e11a6
commit
98957c3509
|
@ -21,6 +21,7 @@ import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.entity.LoadingEntityEntry;
|
import org.hibernate.sql.results.graph.entity.LoadingEntityEntry;
|
||||||
|
import org.hibernate.sql.results.graph.entity.internal.EntityResultInitializer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulates details related to entities which contain sub-select-fetchable
|
* Encapsulates details related to entities which contain sub-select-fetchable
|
||||||
|
@ -180,7 +181,7 @@ public class SubselectFetch {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldAddSubselectFetch(LoadingEntityEntry entry) {
|
private boolean shouldAddSubselectFetch(LoadingEntityEntry entry) {
|
||||||
if ( entry.getEntityInitializer().isEntityResultInitializer() ) {
|
if ( entry.getEntityInitializer() instanceof EntityResultInitializer ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ import static org.hibernate.sql.results.graph.collection.CollectionLoadingLogger
|
||||||
* @implNote Mainly an intention contract wrt the immediacy of the fetch.
|
* @implNote Mainly an intention contract wrt the immediacy of the fetch.
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractImmediateCollectionInitializer extends AbstractCollectionInitializer {
|
public abstract class AbstractImmediateCollectionInitializer extends AbstractCollectionInitializer {
|
||||||
private final LockMode lockMode;
|
|
||||||
|
|
||||||
// per-row state
|
// per-row state
|
||||||
private LoadingCollectionEntryImpl responsibility;
|
private LoadingCollectionEntryImpl responsibility;
|
||||||
|
@ -61,7 +60,6 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
|
||||||
DomainResultAssembler<?> collectionValueKeyResultAssembler) {
|
DomainResultAssembler<?> collectionValueKeyResultAssembler) {
|
||||||
super( collectionPath, collectionAttributeMapping, parentAccess, collectionKeyResultAssembler );
|
super( collectionPath, collectionAttributeMapping, parentAccess, collectionKeyResultAssembler );
|
||||||
this.collectionValueKeyResultAssembler = collectionValueKeyResultAssembler;
|
this.collectionValueKeyResultAssembler = collectionValueKeyResultAssembler;
|
||||||
this.lockMode = lockMode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract String getSimpleConcreteImplName();
|
protected abstract String getSimpleConcreteImplName();
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
import org.hibernate.spi.NavigablePath;
|
import org.hibernate.spi.NavigablePath;
|
||||||
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.entity.EntityInitializer;
|
||||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,6 +30,12 @@ public class DelayedCollectionInitializer extends AbstractCollectionInitializer
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resolveInstance(RowProcessingState rowProcessingState) {
|
public void resolveInstance(RowProcessingState rowProcessingState) {
|
||||||
|
if ( parentAccess != null ) {
|
||||||
|
final EntityInitializer parentEntityInitializer = parentAccess.findFirstEntityInitializer();
|
||||||
|
if ( parentEntityInitializer != null && parentEntityInitializer.isInitialized() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
resolveInstance( rowProcessingState, false );
|
resolveInstance( rowProcessingState, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -143,12 +143,19 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FetchParentAccess findFirstEntityDescriptorAccess() {
|
public FetchParentAccess findFirstEntityDescriptorAccess() {
|
||||||
return getFetchParentAccess().findFirstEntityDescriptorAccess();
|
if ( fetchParentAccess == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return fetchParentAccess.findFirstEntityDescriptorAccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityInitializer findFirstEntityInitializer() {
|
public EntityInitializer findFirstEntityInitializer() {
|
||||||
return findFirstEntityDescriptorAccess().findFirstEntityInitializer();
|
final FetchParentAccess firstEntityDescriptorAccess = findFirstEntityDescriptorAccess();
|
||||||
|
if ( firstEntityDescriptorAccess == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return firstEntityDescriptorAccess.findFirstEntityInitializer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -42,6 +42,7 @@ import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl;
|
import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl;
|
||||||
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
import org.hibernate.proxy.LazyInitializer;
|
import org.hibernate.proxy.LazyInitializer;
|
||||||
import org.hibernate.proxy.map.MapProxy;
|
import org.hibernate.proxy.map.MapProxy;
|
||||||
import org.hibernate.spi.NavigablePath;
|
import org.hibernate.spi.NavigablePath;
|
||||||
|
@ -51,6 +52,7 @@ import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
import org.hibernate.sql.results.graph.basic.BasicResultAssembler;
|
import org.hibernate.sql.results.graph.basic.BasicResultAssembler;
|
||||||
|
import org.hibernate.sql.results.graph.entity.internal.EntityResultInitializer;
|
||||||
import org.hibernate.sql.results.internal.NullValueAssembler;
|
import org.hibernate.sql.results.internal.NullValueAssembler;
|
||||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
|
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
|
||||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingState;
|
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingState;
|
||||||
|
@ -409,7 +411,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
final Object entityInstanceFromExecutionContext =
|
final Object entityInstanceFromExecutionContext =
|
||||||
rowProcessingState.getJdbcValuesSourceProcessingState().getExecutionContext().getEntityInstance();
|
rowProcessingState.getJdbcValuesSourceProcessingState().getExecutionContext().getEntityInstance();
|
||||||
if ( isProxyInstance( proxy ) ) {
|
if ( isProxyInstance( proxy ) ) {
|
||||||
if ( isEntityResultInitializer() && entityInstanceFromExecutionContext != null ) {
|
if ( this instanceof EntityResultInitializer && entityInstanceFromExecutionContext != null ) {
|
||||||
entityInstance = entityInstanceFromExecutionContext;
|
entityInstance = entityInstanceFromExecutionContext;
|
||||||
registerLoadingEntity( rowProcessingState, entityInstance );
|
registerLoadingEntity( rowProcessingState, entityInstance );
|
||||||
}
|
}
|
||||||
|
@ -421,8 +423,12 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
final Object existingEntity = persistenceContext.getEntity( entityKey );
|
final Object existingEntity = persistenceContext.getEntity( entityKey );
|
||||||
if ( existingEntity != null ) {
|
if ( existingEntity != null ) {
|
||||||
entityInstance = existingEntity;
|
entityInstance = existingEntity;
|
||||||
|
if ( existingLoadingEntry == null && isExistingEntityInitialized( existingEntity ) ) {
|
||||||
|
notifyResolutionListeners( entityInstance );
|
||||||
|
this.isInitialized = true;
|
||||||
}
|
}
|
||||||
else if ( isEntityResultInitializer() && entityInstanceFromExecutionContext != null ) {
|
}
|
||||||
|
else if ( this instanceof EntityResultInitializer && entityInstanceFromExecutionContext != null ) {
|
||||||
entityInstance = entityInstanceFromExecutionContext;
|
entityInstance = entityInstanceFromExecutionContext;
|
||||||
registerLoadingEntity( rowProcessingState, entityInstance );
|
registerLoadingEntity( rowProcessingState, entityInstance );
|
||||||
}
|
}
|
||||||
|
@ -457,6 +463,26 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
&& ( proxy instanceof MapProxy || entityDescriptor.getJavaType().getJavaTypeClass().isInstance( proxy ) );
|
&& ( proxy instanceof MapProxy || entityDescriptor.getJavaType().getJavaTypeClass().isInstance( proxy ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isExistingEntityInitialized(Object existingEntity) {
|
||||||
|
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entityInstance );
|
||||||
|
if ( lazyInitializer != null ) {
|
||||||
|
if ( lazyInitializer.isUninitialized() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if ( isPersistentAttributeInterceptable( existingEntity ) ) {
|
||||||
|
final PersistentAttributeInterceptor persistentAttributeInterceptor = asPersistentAttributeInterceptable(
|
||||||
|
entityInstance ).$$_hibernate_getInterceptor();
|
||||||
|
if ( persistentAttributeInterceptor == null || persistentAttributeInterceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check the version of the object in the {@code RowProcessingState} against
|
* Check the version of the object in the {@code RowProcessingState} against
|
||||||
* the object version in the session cache, throwing an exception
|
* the object version in the session cache, throwing an exception
|
||||||
|
@ -953,6 +979,11 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInitialized() {
|
||||||
|
return isInitialized;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityPersister getConcreteDescriptor() {
|
public EntityPersister getConcreteDescriptor() {
|
||||||
return concreteDescriptor;
|
return concreteDescriptor;
|
||||||
|
|
|
@ -60,6 +60,9 @@ public interface EntityInitializer extends FetchParentAccess {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default boolean isInitialized() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
default boolean isEntityResultInitializer() {
|
default boolean isEntityResultInitializer() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -83,6 +83,11 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final EntityInitializer parentEntityInitializer = getParentEntityInitializer( parentAccess );
|
||||||
|
if ( parentEntityInitializer != null && parentEntityInitializer.isInitialized() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( !isAttributeAssignableToConcreteDescriptor( parentAccess, referencedModelPart ) ) {
|
if ( !isAttributeAssignableToConcreteDescriptor( parentAccess, referencedModelPart ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +120,7 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
|
||||||
if ( referencedModelPart.isOptional()
|
if ( referencedModelPart.isOptional()
|
||||||
&& parentAccess != null
|
&& parentAccess != null
|
||||||
&& !parentAccess.isEmbeddableInitializer()
|
&& !parentAccess.isEmbeddableInitializer()
|
||||||
&& isEnhancedForLazyLoading( parentAccess ) ) {
|
&& isEnhancedForLazyLoading( parentEntityInitializer ) ) {
|
||||||
entityInstance = LazyPropertyInitializer.UNFETCHED_PROPERTY;
|
entityInstance = LazyPropertyInitializer.UNFETCHED_PROPERTY;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -141,7 +146,7 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
|
||||||
if ( entityInstance == null ) {
|
if ( entityInstance == null ) {
|
||||||
if ( parentAccess != null
|
if ( parentAccess != null
|
||||||
&& !parentAccess.isEmbeddableInitializer()
|
&& !parentAccess.isEmbeddableInitializer()
|
||||||
&& isEnhancedForLazyLoading( parentAccess ) ) {
|
&& isEnhancedForLazyLoading( parentEntityInitializer ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
entityInstance = ( (UniqueKeyLoadable) concreteDescriptor ).loadByUniqueKey(
|
entityInstance = ( (UniqueKeyLoadable) concreteDescriptor ).loadByUniqueKey(
|
||||||
|
@ -180,8 +185,16 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isEnhancedForLazyLoading(FetchParentAccess parentAccess) {
|
private EntityInitializer getParentEntityInitializer(FetchParentAccess parentAccess) {
|
||||||
return parentAccess.findFirstEntityInitializer().getEntityDescriptor().getBytecodeEnhancementMetadata()
|
if ( parentAccess != null ) {
|
||||||
|
return parentAccess.findFirstEntityInitializer();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isEnhancedForLazyLoading(EntityInitializer parentEntityIntialiazer) {
|
||||||
|
return parentEntityIntialiazer != null && parentEntityIntialiazer.getEntityDescriptor()
|
||||||
|
.getBytecodeEnhancementMetadata()
|
||||||
.isEnhancedForLazyLoading();
|
.isEnhancedForLazyLoading();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,4 +251,9 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
|
||||||
return "EntityDelayedFetchInitializer(" + LoggingHelper.toLoggableString( navigablePath ) + ")";
|
return "EntityDelayedFetchInitializer(" + LoggingHelper.toLoggableString( navigablePath ) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEntityResultInitializer() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,8 +57,4 @@ public class EntityResultInitializer extends AbstractEntityInitializer {
|
||||||
return CONCRETE_NAME + "(" + getNavigablePath() + ")";
|
return CONCRETE_NAME + "(" + getNavigablePath() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEntityResultInitializer() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import java.util.function.BiConsumer;
|
||||||
import org.hibernate.engine.spi.CollectionKey;
|
import org.hibernate.engine.spi.CollectionKey;
|
||||||
import org.hibernate.engine.spi.EntityKey;
|
import org.hibernate.engine.spi.EntityKey;
|
||||||
import org.hibernate.engine.spi.EntityUniqueKey;
|
import org.hibernate.engine.spi.EntityUniqueKey;
|
||||||
|
import org.hibernate.engine.spi.PersistenceContext;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.event.service.spi.EventListenerGroup;
|
import org.hibernate.event.service.spi.EventListenerGroup;
|
||||||
import org.hibernate.event.spi.EventSource;
|
import org.hibernate.event.spi.EventSource;
|
||||||
|
|
Loading…
Reference in New Issue