HHH-17359 Assemble key for select fetch initializers in resolveInstance phase
This commit is contained in:
parent
25c2d6ac48
commit
52e6e1fc0f
|
@ -517,12 +517,12 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
else {
|
||||
entityInstance = proxy;
|
||||
if ( Hibernate.isInitialized( entityInstance ) ) {
|
||||
this.isInitialized = true;
|
||||
registerReloadedEntity( rowProcessingState, holder );
|
||||
if ( rowProcessingState.getQueryOptions().isResultCachingEnabled() == Boolean.TRUE ) {
|
||||
// We need to read result set values to correctly populate the query cache
|
||||
resolveState( rowProcessingState );
|
||||
}
|
||||
this.isInitialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -532,13 +532,13 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
entityInstance = existingEntity;
|
||||
if ( holder.getEntityInitializer() == null ) {
|
||||
if ( isExistingEntityInitialized( existingEntity ) ) {
|
||||
this.isInitialized = true;
|
||||
registerReloadedEntity( rowProcessingState, holder );
|
||||
notifyResolutionListeners( entityInstance );
|
||||
if ( rowProcessingState.getQueryOptions().isResultCachingEnabled() == Boolean.TRUE ) {
|
||||
// We need to read result set values to correctly populate the query cache
|
||||
resolveState( rowProcessingState );
|
||||
}
|
||||
this.isInitialized = true;
|
||||
}
|
||||
else {
|
||||
registerLoadingEntityInstanceFromExecutionContext( rowProcessingState, entityInstance );
|
||||
|
|
|
@ -10,8 +10,10 @@ import org.hibernate.engine.spi.EntityUniqueKey;
|
|||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.log.LoggingHelper;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.spi.EntityIdentifierNavigablePath;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||
|
@ -37,31 +39,55 @@ public class EntitySelectFetchByUniqueKeyInitializer extends EntitySelectFetchIn
|
|||
}
|
||||
|
||||
@Override
|
||||
public void initializeInstance(RowProcessingState rowProcessingState) {
|
||||
if ( entityInstance != null || isInitialized ) {
|
||||
public void resolveInstance(RowProcessingState rowProcessingState) {
|
||||
if ( state != State.UNINITIALIZED ) {
|
||||
return;
|
||||
}
|
||||
state = State.RESOLVED;
|
||||
|
||||
final EntityInitializer parentEntityInitializer = getParentEntityInitializer( parentAccess );
|
||||
if ( parentEntityInitializer != null && parentEntityInitializer.getEntityKey() != null ) {
|
||||
// make sure parentEntityInitializer.resolveInstance has been called before
|
||||
parentEntityInitializer.resolveInstance( rowProcessingState );
|
||||
if ( parentEntityInitializer.isEntityInitialized() ) {
|
||||
isInitialized = true;
|
||||
state = State.INITIALIZED;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !isAttributeAssignableToConcreteDescriptor() ) {
|
||||
isInitialized = true;
|
||||
state = State.INITIALIZED;
|
||||
return;
|
||||
}
|
||||
|
||||
final Object entityIdentifier = keyAssembler.assemble( rowProcessingState );
|
||||
entityIdentifier = keyAssembler.assemble( rowProcessingState );
|
||||
if ( entityIdentifier == null ) {
|
||||
isInitialized = true;
|
||||
state = State.INITIALIZED;
|
||||
return;
|
||||
}
|
||||
|
||||
// Defer the select by default to the initialize phase
|
||||
// We only need to select in this phase if this is part of an identifier or foreign key
|
||||
NavigablePath np = getNavigablePath().getParent();
|
||||
while ( np != null ) {
|
||||
if ( np instanceof EntityIdentifierNavigablePath
|
||||
|| ForeignKeyDescriptor.PART_NAME.equals( np.getLocalName() )
|
||||
|| ForeignKeyDescriptor.TARGET_PART_NAME.equals( np.getLocalName() )) {
|
||||
|
||||
initializeInstance( rowProcessingState );
|
||||
return;
|
||||
}
|
||||
np = np.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeInstance(RowProcessingState rowProcessingState) {
|
||||
if ( state == State.INITIALIZED ) {
|
||||
return;
|
||||
}
|
||||
state = State.INITIALIZED;
|
||||
|
||||
final String entityName = concreteDescriptor.getEntityName();
|
||||
final String uniqueKeyPropertyName = fetchedAttribute.getReferencedPropertyName();
|
||||
|
||||
|
@ -103,7 +129,6 @@ public class EntitySelectFetchByUniqueKeyInitializer extends EntitySelectFetchIn
|
|||
if ( entityInstance != null ) {
|
||||
entityInstance = persistenceContext.proxyFor( entityInstance );
|
||||
}
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
private EntityInitializer getParentEntityInitializer(FetchParentAccess parentAccess) {
|
||||
|
|
|
@ -48,15 +48,15 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
|
|||
protected final DomainResultAssembler<?> keyAssembler;
|
||||
private final ToOneAttributeMapping toOneMapping;
|
||||
|
||||
protected boolean isInitialized;
|
||||
protected State state = State.UNINITIALIZED;
|
||||
protected Object entityIdentifier;
|
||||
protected Object entityInstance;
|
||||
|
||||
@Override
|
||||
public FetchParentAccess getFetchParentAccess() {
|
||||
return parentAccess;
|
||||
}
|
||||
|
||||
protected Object entityInstance;
|
||||
|
||||
public EntitySelectFetchInitializer(
|
||||
FetchParentAccess parentAccess,
|
||||
ToOneAttributeMapping toOneMapping,
|
||||
|
@ -87,41 +87,26 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
|
|||
|
||||
@Override
|
||||
public void resolveInstance(RowProcessingState rowProcessingState) {
|
||||
// Defer the select by default to the initialize phase
|
||||
// We only need to select in this phase if this is part of an identifier or foreign key
|
||||
NavigablePath np = navigablePath.getParent();
|
||||
while ( np != null ) {
|
||||
if ( np instanceof EntityIdentifierNavigablePath
|
||||
|| ForeignKeyDescriptor.PART_NAME.equals( np.getLocalName() )
|
||||
|| ForeignKeyDescriptor.TARGET_PART_NAME.equals( np.getLocalName() )) {
|
||||
|
||||
initializeInstance( rowProcessingState );
|
||||
return;
|
||||
}
|
||||
np = np.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeInstance(RowProcessingState rowProcessingState) {
|
||||
if ( entityInstance != null || isInitialized ) {
|
||||
if ( state != State.UNINITIALIZED ) {
|
||||
return;
|
||||
}
|
||||
state = State.RESOLVED;
|
||||
|
||||
final EntityInitializer parentEntityInitializer = parentAccess.findFirstEntityInitializer();
|
||||
if ( parentEntityInitializer != null && parentEntityInitializer.isEntityInitialized() ) {
|
||||
isInitialized = true;
|
||||
state = State.INITIALIZED;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !isAttributeAssignableToConcreteDescriptor() ) {
|
||||
state = State.INITIALIZED;
|
||||
return;
|
||||
}
|
||||
|
||||
final Object entityIdentifier = keyAssembler.assemble( rowProcessingState );
|
||||
entityIdentifier = keyAssembler.assemble( rowProcessingState );
|
||||
|
||||
if ( entityIdentifier == null ) {
|
||||
isInitialized = true;
|
||||
state = State.INITIALIZED;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -134,8 +119,6 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
|
|||
);
|
||||
}
|
||||
final SharedSessionContractImplementor session = rowProcessingState.getSession();
|
||||
final String entityName = concreteDescriptor.getEntityName();
|
||||
|
||||
final EntityKey entityKey = new EntityKey( entityIdentifier, concreteDescriptor );
|
||||
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
||||
|
@ -154,7 +137,7 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
|
|||
entityInstance = holder.getEntity();
|
||||
if ( holder.getEntityInitializer() == null ) {
|
||||
if ( entityInstance != null && Hibernate.isInitialized( entityInstance ) ) {
|
||||
isInitialized = true;
|
||||
state = State.INITIALIZED;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -168,15 +151,39 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
|
|||
holder.getEntityInitializer()
|
||||
);
|
||||
}
|
||||
isInitialized = true;
|
||||
state = State.INITIALIZED;
|
||||
return;
|
||||
}
|
||||
else if ( entityInstance == null ) {
|
||||
isInitialized = true;
|
||||
state = State.INITIALIZED;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Defer the select by default to the initialize phase
|
||||
// We only need to select in this phase if this is part of an identifier or foreign key
|
||||
NavigablePath np = navigablePath.getParent();
|
||||
while ( np != null ) {
|
||||
if ( np instanceof EntityIdentifierNavigablePath
|
||||
|| ForeignKeyDescriptor.PART_NAME.equals( np.getLocalName() )
|
||||
|| ForeignKeyDescriptor.TARGET_PART_NAME.equals( np.getLocalName() )) {
|
||||
|
||||
initializeInstance( rowProcessingState );
|
||||
return;
|
||||
}
|
||||
np = np.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeInstance(RowProcessingState rowProcessingState) {
|
||||
if ( state == State.INITIALIZED ) {
|
||||
return;
|
||||
}
|
||||
state = State.INITIALIZED;
|
||||
final SharedSessionContractImplementor session = rowProcessingState.getSession();
|
||||
final String entityName = concreteDescriptor.getEntityName();
|
||||
|
||||
if ( EntityLoadingLogging.ENTITY_LOADING_LOGGER.isDebugEnabled() ) {
|
||||
EntityLoadingLogging.ENTITY_LOADING_LOGGER.debugf(
|
||||
"(%s) Invoking session#internalLoad for entity (%s) : %s",
|
||||
|
@ -197,7 +204,7 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
|
|||
throw new FetchNotFoundException( entityName, entityIdentifier );
|
||||
}
|
||||
rowProcessingState.getSession().getPersistenceContextInternal().claimEntityHolderIfPossible(
|
||||
entityKey,
|
||||
new EntityKey( entityIdentifier, concreteDescriptor ),
|
||||
entityInstance,
|
||||
rowProcessingState.getJdbcValuesSourceProcessingState(),
|
||||
this
|
||||
|
@ -218,8 +225,6 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
|
|||
if ( lazyInitializer != null ) {
|
||||
lazyInitializer.setUnwrap( unwrapProxy );
|
||||
}
|
||||
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
protected boolean isAttributeAssignableToConcreteDescriptor() {
|
||||
|
@ -229,7 +234,7 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
|
|||
@Override
|
||||
public void finishUpRow(RowProcessingState rowProcessingState) {
|
||||
entityInstance = null;
|
||||
isInitialized = false;
|
||||
state = State.UNINITIALIZED;
|
||||
clearResolutionListeners();
|
||||
}
|
||||
|
||||
|
@ -250,7 +255,7 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
|
|||
|
||||
@Override
|
||||
public boolean isEntityInitialized() {
|
||||
return isInitialized;
|
||||
return state == State.INITIALIZED;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -277,4 +282,10 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
|
|||
public String toString() {
|
||||
return "EntitySelectFetchInitializer(" + LoggingHelper.toLoggableString( getNavigablePath() ) + ")";
|
||||
}
|
||||
|
||||
protected enum State {
|
||||
UNINITIALIZED,
|
||||
RESOLVED,
|
||||
INITIALIZED;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue