Skip to content

some minor refactorings to Initializers #10317

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
import org.hibernate.engine.spi.EntityHolder;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;
import org.hibernate.spi.NavigablePath;
import org.hibernate.sql.results.graph.AssemblerCreationState;
Expand All @@ -39,7 +37,8 @@ public abstract class AbstractBatchEntitySelectFetchInitializer<Data extends Abs

protected final EntityInitializer<InitializerData> owningEntityInitializer;

public static abstract class AbstractBatchEntitySelectFetchInitializerData extends EntitySelectFetchInitializerData {
public static abstract class AbstractBatchEntitySelectFetchInitializerData
extends EntitySelectFetchInitializerData {
final boolean batchDisabled;

// per-row state
Expand All @@ -48,10 +47,11 @@ public static abstract class AbstractBatchEntitySelectFetchInitializerData exten
public AbstractBatchEntitySelectFetchInitializerData(
AbstractBatchEntitySelectFetchInitializer<?> initializer,
RowProcessingState rowProcessingState) {
super( initializer, rowProcessingState );
super( rowProcessingState );

batchDisabled = rowProcessingState.isScrollResult()
|| !rowProcessingState.getLoadQueryInfluencers().effectivelyBatchLoadable( initializer.toOneMapping.getEntityMappingType().getEntityPersister() );
|| !rowProcessingState.getLoadQueryInfluencers()
.effectivelyBatchLoadable( initializer.toOneMapping.getEntityMappingType().getEntityPersister() );
}
}

Expand All @@ -73,51 +73,47 @@ public AbstractBatchEntitySelectFetchInitializer(

@Override
public void resolveKey(Data data) {
if ( data.getState() != State.UNINITIALIZED ) {
return;
}

data.entityKey = null;
data.setInstance( null );
final RowProcessingState rowProcessingState = data.getRowProcessingState();
//noinspection unchecked
final Initializer<InitializerData> initializer = (Initializer<InitializerData>) keyAssembler.getInitializer();
if ( initializer != null ) {
final InitializerData subData = initializer.getData( rowProcessingState );
initializer.resolveKey( subData );
data.entityIdentifier = null;
data.setState( subData.getState() == State.MISSING ? State.MISSING : State.KEY_RESOLVED );
}
else {
data.entityIdentifier = keyAssembler.assemble( rowProcessingState );
data.setState( data.entityIdentifier == null ? State.MISSING : State.KEY_RESOLVED );
if ( data.getState() == State.UNINITIALIZED ) {
data.entityKey = null;
data.setInstance( null );
final RowProcessingState rowProcessingState = data.getRowProcessingState();
//noinspection unchecked
final Initializer<InitializerData> initializer = (Initializer<InitializerData>) keyAssembler.getInitializer();
if ( initializer != null ) {
final InitializerData subData = initializer.getData( rowProcessingState );
initializer.resolveKey( subData );
data.entityIdentifier = null;
data.setState( subData.getState() == State.MISSING ? State.MISSING : State.KEY_RESOLVED );
}
else {
data.entityIdentifier = keyAssembler.assemble( rowProcessingState );
data.setState( data.entityIdentifier == null ? State.MISSING : State.KEY_RESOLVED );
}
}
}

@Override
public void resolveInstance(Data data) {
if ( data.getState() != State.KEY_RESOLVED ) {
return;
}

data.setState( State.RESOLVED );
final RowProcessingState rowProcessingState = data.getRowProcessingState();
if ( data.entityIdentifier == null ) {
// entityIdentifier can be null if the identifier is based on an initializer
data.entityIdentifier = keyAssembler.assemble( rowProcessingState );
if ( data.getState() == State.KEY_RESOLVED ) {
data.setState( State.RESOLVED );
final RowProcessingState rowProcessingState = data.getRowProcessingState();
if ( data.entityIdentifier == null ) {
data.entityKey = null;
data.setInstance( null );
data.setState( State.MISSING );
return;
// entityIdentifier can be null if the identifier is based on an initializer
data.entityIdentifier = keyAssembler.assemble( rowProcessingState );
if ( data.entityIdentifier == null ) {
data.entityKey = null;
data.setInstance( null );
data.setState( State.MISSING );
return;
}
}
resolveInstanceFromIdentifier( data );
}
resolveInstanceFromIdentifier( data );
}

protected void resolveInstanceFromIdentifier(Data data) {
if ( data.batchDisabled ) {
initialize( data );
initializeIfNecessary( data );
}
else {
data.entityKey = new EntityKey( data.entityIdentifier, concreteDescriptor );
Expand All @@ -136,87 +132,92 @@ public void resolveInstance(Object instance, Data data) {
data.setState( State.MISSING );
data.entityKey = null;
data.setInstance( null );
return;
}
final RowProcessingState rowProcessingState = data.getRowProcessingState();
// Only need to extract the identifier if the identifier has a many to one
final LazyInitializer lazyInitializer = extractLazyInitializer( instance );
data.entityKey = null;
data.entityIdentifier = null;
if ( lazyInitializer == null ) {
// Entity is most probably initialized
data.setInstance( instance );
if ( concreteDescriptor.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading()
&& isPersistentAttributeInterceptable( instance )
&& getAttributeInterceptor( instance )
instanceof EnhancementAsProxyLazinessInterceptor enhancementInterceptor ) {
if ( enhancementInterceptor.isInitialized() ) {
data.setState( State.INITIALIZED );
else {
final RowProcessingState rowProcessingState = data.getRowProcessingState();
// Only need to extract the identifier if the identifier has a many to one
final LazyInitializer lazyInitializer = extractLazyInitializer( instance );
data.entityKey = null;
data.entityIdentifier = null;
if ( lazyInitializer == null ) {
// Entity is most probably initialized
data.setInstance( instance );
if ( concreteDescriptor.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading()
&& isPersistentAttributeInterceptable( instance )
&& getAttributeInterceptor( instance )
instanceof EnhancementAsProxyLazinessInterceptor enhancementInterceptor ) {
if ( enhancementInterceptor.isInitialized() ) {
data.setState( State.INITIALIZED );
}
else {
data.setState( State.RESOLVED );
data.entityIdentifier = enhancementInterceptor.getIdentifier();
}
if ( keyIsEager && data.entityIdentifier == null ) {
data.entityIdentifier =
concreteDescriptor.getIdentifier( instance, rowProcessingState.getSession() );
}
}
else {
// If the entity initializer is null, we know the entity is fully initialized,
// otherwise it will be initialized by some other initializer
data.setState( State.RESOLVED );
data.entityIdentifier = enhancementInterceptor.getIdentifier();
data.entityIdentifier =
concreteDescriptor.getIdentifier( instance, rowProcessingState.getSession() );
}
}
else {
// If the entity initializer is null, we know the entity is fully initialized,
// otherwise it will be initialized by some other initializer
else if ( lazyInitializer.isUninitialized() ) {
data.setState( State.RESOLVED );
data.entityIdentifier = concreteDescriptor.getIdentifier( instance, rowProcessingState.getSession() );
data.entityIdentifier = lazyInitializer.getInternalIdentifier();
}
else {
// Entity is initialized
data.setState( State.INITIALIZED );
if ( keyIsEager ) {
data.entityIdentifier = lazyInitializer.getInternalIdentifier();
}
data.setInstance( lazyInitializer.getImplementation() );
}
if ( keyIsEager && data.entityIdentifier == null ) {
data.entityIdentifier = concreteDescriptor.getIdentifier( instance, rowProcessingState.getSession() );

if ( data.getState() == State.RESOLVED ) {
resolveInstanceFromIdentifier( data );
}
}
else if ( lazyInitializer.isUninitialized() ) {
data.setState( State.RESOLVED );
data.entityIdentifier = lazyInitializer.getInternalIdentifier();
}
else {
// Entity is initialized
data.setState( State.INITIALIZED );
if ( keyIsEager ) {
data.entityIdentifier = lazyInitializer.getInternalIdentifier();
final Initializer<?> initializer = keyAssembler.getInitializer();
assert initializer != null;
initializer.resolveInstance( data.entityIdentifier, rowProcessingState );
}
else if ( rowProcessingState.needsResolveState() ) {
// Resolve the state of the identifier if result caching is enabled and this is not a query cache hit
keyAssembler.resolveState( rowProcessingState );
}
data.setInstance( lazyInitializer.getImplementation() );
}

if ( data.getState() == State.RESOLVED ) {
resolveInstanceFromIdentifier( data );
}
if ( keyIsEager ) {
final Initializer<?> initializer = keyAssembler.getInitializer();
assert initializer != null;
initializer.resolveInstance( data.entityIdentifier, rowProcessingState );
}
else if ( rowProcessingState.needsResolveState() ) {
// Resolve the state of the identifier if result caching is enabled and this is not a query cache hit
keyAssembler.resolveState( rowProcessingState );
}
}

@Override
public void initializeInstance(Data data) {
if ( data.getState() != State.RESOLVED ) {
return;
}
data.setState( State.INITIALIZED );
if ( data.batchDisabled ) {
Hibernate.initialize( data.getInstance() );
if ( data.getState() == State.RESOLVED ) {
data.setState( State.INITIALIZED );
if ( data.batchDisabled ) {
Hibernate.initialize( data.getInstance() );
}
}
}

protected Object getExistingInitializedInstance(Data data) {
final SharedSessionContractImplementor session = data.getRowProcessingState().getSession();
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
final EntityHolder holder = persistenceContext.getEntityHolder( data.entityKey );
final EntityHolder holder =
data.getRowProcessingState().getSession()
.getPersistenceContextInternal()
.getEntityHolder( data.entityKey );
if ( holder != null && holder.getEntity() != null && holder.isEventuallyInitialized() ) {
return holder.getEntity();
}
// we need to register a resolution listener only if there is not an already initialized instance
// or an instance that another initializer is loading
registerResolutionListener( data );
return null;
else {
// we need to register a resolution listener only if there is not an already initialized instance
// or an instance that another initializer is loading
registerResolutionListener( data );
return null;
}
}

protected void registerToBatchFetchQueue(Data data) {
Expand All @@ -238,7 +239,7 @@ public void initializeInstanceFromParent(Object parentInstance, Data data) {
data.setState( State.MISSING );
}
else {
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( instance );
final LazyInitializer lazyInitializer = extractLazyInitializer( instance );
if ( lazyInitializer != null && lazyInitializer.isUninitialized() ) {
data.entityKey = new EntityKey( lazyInitializer.getInternalIdentifier(), concreteDescriptor );
registerToBatchFetchQueue( data );
Expand Down Expand Up @@ -277,22 +278,13 @@ protected static Object loadInstance(

protected AttributeMapping[] getParentEntityAttributes(String attributeName) {
final EntityPersister entityDescriptor = owningEntityInitializer.getEntityDescriptor();
final AttributeMapping[] parentEntityAttributes = new AttributeMapping[
entityDescriptor.getRootEntityDescriptor()
.getSubclassEntityNames()
.size()
];
parentEntityAttributes[entityDescriptor.getSubclassId()] = getParentEntityAttribute(
entityDescriptor,
toOneMapping,
attributeName
);
final int size = entityDescriptor.getRootEntityDescriptor().getSubclassEntityNames().size();
final AttributeMapping[] parentEntityAttributes = new AttributeMapping[size];
parentEntityAttributes[entityDescriptor.getSubclassId()] =
getParentEntityAttribute( entityDescriptor, toOneMapping, attributeName );
for ( EntityMappingType subMappingType : entityDescriptor.getSubMappingTypes() ) {
parentEntityAttributes[subMappingType.getSubclassId()] = getParentEntityAttribute(
subMappingType,
toOneMapping,
attributeName
);
parentEntityAttributes[subMappingType.getSubclassId()] =
getParentEntityAttribute( subMappingType, toOneMapping, attributeName );
}
return parentEntityAttributes;
}
Expand All @@ -302,8 +294,9 @@ protected static AttributeMapping getParentEntityAttribute(
ToOneAttributeMapping referencedModelPart,
String attributeName) {
final AttributeMapping parentAttribute = subMappingType.findAttributeMapping( attributeName );
if ( parentAttribute != null && parentAttribute.getDeclaringType() == referencedModelPart.getDeclaringType()
.findContainingEntityMapping() ) {
if ( parentAttribute != null
&& parentAttribute.getDeclaringType()
== referencedModelPart.getDeclaringType().findContainingEntityMapping() ) {
// These checks are needed to avoid setting the instance using the wrong (child's) model part or
// setting it multiple times in case parent and child share the same attribute name for the association.
return parentAttribute;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
*/
package org.hibernate.sql.results.graph.entity.internal;

import org.hibernate.EntityFilterException;
import org.hibernate.FetchNotFoundException;
import org.hibernate.annotations.NotFoundAction;
import org.hibernate.engine.spi.EntityUniqueKey;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
Expand Down Expand Up @@ -37,7 +34,7 @@ public EntitySelectFetchByUniqueKeyInitializer(
}

@Override
protected void initialize(EntitySelectFetchInitializerData data) {
protected void initializeIfNecessary(EntitySelectFetchInitializerData data) {
final String entityName = concreteDescriptor.getEntityName();
final String uniqueKeyPropertyName = fetchedAttribute.getReferencedPropertyName();

Expand All @@ -61,18 +58,7 @@ protected void initialize(EntitySelectFetchInitializerData data) {
data.setInstance( instance );

if ( instance == null ) {
if ( toOneMapping.getNotFoundAction() != NotFoundAction.IGNORE ) {
if ( affectedByFilter ) {
throw new EntityFilterException(
entityName,
data.entityIdentifier,
toOneMapping.getNavigableRole().getFullPath()
);
}
if ( toOneMapping.getNotFoundAction() == NotFoundAction.EXCEPTION ) {
throw new FetchNotFoundException( entityName, data.entityIdentifier );
}
}
handleNotFound( data, entityName );
}
// If the entity was not in the Persistence Context, but was found now,
// add it to the Persistence Context
Expand Down
Loading
Loading