HHH-17783 Allow early initialization of entity instance by non-owning initializer
This commit is contained in:
parent
710ea629a9
commit
44aec90538
|
@ -22,6 +22,7 @@ import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
|
||||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asSelfDirtinessTracker;
|
import static org.hibernate.engine.internal.ManagedTypeHelper.asSelfDirtinessTracker;
|
||||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isSelfDirtinessTrackerType;
|
import static org.hibernate.engine.internal.ManagedTypeHelper.isSelfDirtinessTrackerType;
|
||||||
|
|
||||||
|
@ -215,23 +216,7 @@ public class EnhancementAsProxyLazinessInterceptor extends AbstractLazyLoadInter
|
||||||
|
|
||||||
if ( isTemporarySession ) {
|
if ( isTemporarySession ) {
|
||||||
// Add an entry for this entity in the PC of the temp Session
|
// Add an entry for this entity in the PC of the temp Session
|
||||||
session.getPersistenceContextInternal().addEntity(
|
session.getPersistenceContext().addEnhancedProxy( entityKey, asPersistentAttributeInterceptable( target ) );
|
||||||
target,
|
|
||||||
org.hibernate.engine.spi.Status.READ_ONLY,
|
|
||||||
// loaded state
|
|
||||||
ArrayHelper.filledArray(
|
|
||||||
LazyPropertyInitializer.UNFETCHED_PROPERTY,
|
|
||||||
Object.class,
|
|
||||||
persister.getPropertyTypes().length
|
|
||||||
),
|
|
||||||
entityKey,
|
|
||||||
persister.getVersion( target ),
|
|
||||||
LockMode.NONE,
|
|
||||||
// we assume an entry exists in the db
|
|
||||||
true,
|
|
||||||
persister,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return persister.initializeEnhancedEntityUsedAsProxy(
|
return persister.initializeEnhancedEntityUsedAsProxy(
|
||||||
|
|
|
@ -516,6 +516,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
||||||
final Object entity = holder.entity;
|
final Object entity = holder.entity;
|
||||||
if ( holder.proxy != null ) {
|
if ( holder.proxy != null ) {
|
||||||
holder.entity = null;
|
holder.entity = null;
|
||||||
|
holder.state = EntityHolderState.UNINITIALIZED;
|
||||||
entitiesByKey.put( key, holder );
|
entitiesByKey.put( key, holder );
|
||||||
}
|
}
|
||||||
return entity;
|
return entity;
|
||||||
|
@ -2199,6 +2200,11 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
||||||
processingState.registerReloadedEntityHolder( this );
|
processingState.registerReloadedEntityHolder( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInitialized() {
|
||||||
|
return state == EntityHolderState.INITIALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEventuallyInitialized() {
|
public boolean isEventuallyInitialized() {
|
||||||
return state == EntityHolderState.INITIALIZED || entityInitializer != null;
|
return state == EntityHolderState.INITIALIZED || entityInitializer != null;
|
||||||
|
|
|
@ -52,6 +52,11 @@ public interface EntityHolder {
|
||||||
*/
|
*/
|
||||||
void markAsReloaded(JdbcValuesSourceProcessingState processingState);
|
void markAsReloaded(JdbcValuesSourceProcessingState processingState);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the entity is already initialized
|
||||||
|
*/
|
||||||
|
boolean isInitialized();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the entity is already initialized or will be initialized through an initializer eventually.
|
* Whether the entity is already initialized or will be initialized through an initializer eventually.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -114,6 +114,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
private Object version;
|
private Object version;
|
||||||
private Object entityInstance;
|
private Object entityInstance;
|
||||||
protected Object entityInstanceForNotify;
|
protected Object entityInstanceForNotify;
|
||||||
|
private EntityHolder holder;
|
||||||
protected State state = State.UNINITIALIZED;
|
protected State state = State.UNINITIALIZED;
|
||||||
private boolean isOwningInitializer;
|
private boolean isOwningInitializer;
|
||||||
private Object[] resolvedEntityState;
|
private Object[] resolvedEntityState;
|
||||||
|
@ -444,7 +445,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
// even if the parent instance will not refer to this entity.
|
// even if the parent instance will not refer to this entity.
|
||||||
|
|
||||||
final PersistenceContext persistenceContext = rowProcessingState.getSession().getPersistenceContextInternal();
|
final PersistenceContext persistenceContext = rowProcessingState.getSession().getPersistenceContextInternal();
|
||||||
final EntityHolder holder = persistenceContext.claimEntityHolderIfPossible(
|
holder = persistenceContext.claimEntityHolderIfPossible(
|
||||||
entityKey,
|
entityKey,
|
||||||
null,
|
null,
|
||||||
rowProcessingState.getJdbcValuesSourceProcessingState(),
|
rowProcessingState.getJdbcValuesSourceProcessingState(),
|
||||||
|
@ -544,9 +545,6 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
registerLoadingEntity( rowProcessingState, entityInstance );
|
registerLoadingEntity( rowProcessingState, entityInstance );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( !isOwningInitializer ) {
|
|
||||||
state = State.INITIALIZED;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if ( ( entityFromExecutionContext = getEntityFromExecutionContext( rowProcessingState ) ) != null ) {
|
else if ( ( entityFromExecutionContext = getEntityFromExecutionContext( rowProcessingState ) ) != null ) {
|
||||||
// This is the entity to refresh, so don't set the state to initialized
|
// This is the entity to refresh, so don't set the state to initialized
|
||||||
|
@ -1050,8 +1048,9 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean skipInitialization(Object toInitialize, RowProcessingState rowProcessingState) {
|
protected boolean skipInitialization(Object toInitialize, RowProcessingState rowProcessingState) {
|
||||||
if ( !isOwningInitializer ) {
|
if ( holder.isInitialized() ) {
|
||||||
return true;
|
return rowProcessingState.getJdbcValuesSourceProcessingState().getProcessingOptions()
|
||||||
|
.getEffectiveOptionalObject() != toInitialize;
|
||||||
}
|
}
|
||||||
final EntityEntry entry =
|
final EntityEntry entry =
|
||||||
rowProcessingState.getSession().getPersistenceContextInternal().getEntry( toInitialize );
|
rowProcessingState.getSession().getPersistenceContextInternal().getEntry( toInitialize );
|
||||||
|
@ -1062,7 +1061,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
else if ( entry.getStatus().isDeletedOrGone() ) {
|
else if ( entry.getStatus().isDeletedOrGone() ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else if ( isOwningInitializer ) {
|
||||||
if ( isPersistentAttributeInterceptable( toInitialize ) ) {
|
if ( isPersistentAttributeInterceptable( toInitialize ) ) {
|
||||||
final PersistentAttributeInterceptor interceptor =
|
final PersistentAttributeInterceptor interceptor =
|
||||||
asPersistentAttributeInterceptable( toInitialize ).$$_hibernate_getInterceptor();
|
asPersistentAttributeInterceptable( toInitialize ).$$_hibernate_getInterceptor();
|
||||||
|
@ -1085,6 +1084,9 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isReadOnly(RowProcessingState rowProcessingState, SharedSessionContractImplementor persistenceContext) {
|
private boolean isReadOnly(RowProcessingState rowProcessingState, SharedSessionContractImplementor persistenceContext) {
|
||||||
|
|
|
@ -154,7 +154,7 @@ public class EntitySelectFetchInitializer implements EntityInitializer {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
entityInstance = holder.getEntity();
|
entityInstance = persistenceContext.proxyFor( holder, concreteDescriptor );
|
||||||
if ( holder.getEntityInitializer() == null ) {
|
if ( holder.getEntityInitializer() == null ) {
|
||||||
if ( entityInstance != null && Hibernate.isInitialized( entityInstance ) ) {
|
if ( entityInstance != null && Hibernate.isInitialized( entityInstance ) ) {
|
||||||
state = State.INITIALIZED;
|
state = State.INITIALIZED;
|
||||||
|
|
Loading…
Reference in New Issue