Skip to content
Merged
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 @@ -297,6 +297,10 @@ public void resolveInstance(@Nullable Object instance, NonAggregatedIdentifierMa
data.setState( State.MISSING );
data.setInstance( null );
}
else if ( hasIdClass ) {
resolveKey( data );
resolveInstance( data );
}
else {
data.setState( State.INITIALIZED );
data.setInstance( instance );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,11 @@ public void resolveInstance(Object instance, Data data) {
data.setInstance( null );
return;
}
final RowProcessingState rowProcessingState = data.getRowProcessingState();
final var rowProcessingState = data.getRowProcessingState();
final var session = rowProcessingState.getSession();
final var persistenceContext = session.getPersistenceContextInternal();
// 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
Expand All @@ -162,10 +163,10 @@ && getAttributeInterceptor( instance )
// 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 = concreteDescriptor.getIdentifier( instance, rowProcessingState.getSession() );
data.entityIdentifier = concreteDescriptor.getIdentifier( instance, session );
}
if ( keyIsEager && data.entityIdentifier == null ) {
data.entityIdentifier = concreteDescriptor.getIdentifier( instance, rowProcessingState.getSession() );
if ( data.entityIdentifier == null ) {
data.entityIdentifier = concreteDescriptor.getIdentifier( instance, session );
}
}
else if ( lazyInitializer.isUninitialized() ) {
Expand All @@ -175,15 +176,47 @@ else if ( lazyInitializer.isUninitialized() ) {
else {
// Entity is initialized
data.setState( State.INITIALIZED );
if ( keyIsEager ) {
data.entityIdentifier = lazyInitializer.getInternalIdentifier();
}
data.entityIdentifier = lazyInitializer.getInternalIdentifier();
data.setInstance( lazyInitializer.getImplementation() );
}

data.entityKey = new EntityKey( data.entityIdentifier, concreteDescriptor );
final var entityHolder = persistenceContext.getEntityHolder(
data.entityKey
);

if ( entityHolder == null || entityHolder.getEntity() != instance && entityHolder.getProxy() != instance ) {
// the existing entity instance is detached or transient
if ( entityHolder != null ) {
final var managed = entityHolder.getManagedObject();
data.setInstance( managed );
data.entityKey = entityHolder.getEntityKey();
data.entityIdentifier = data.entityKey.getIdentifier();
if ( entityHolder.isInitialized() ) {
data.setState( State.INITIALIZED );
}
else {
data.setState( State.RESOLVED );
}
}
else {
data.setState( State.RESOLVED );
}
}

if ( data.getState() == State.RESOLVED ) {
resolveInstanceFromIdentifier( data );
// similar to resolveInstanceFromIdentifier, but we already have the holder here
if ( data.batchDisabled ) {
initialize( data, entityHolder, session, persistenceContext );
}
else if ( entityHolder == null || !entityHolder.isEventuallyInitialized() ) {
// need to add the key to the batch queue only when the entity has not been already loaded or
// there isn't another initializer that is loading it
registerResolutionListener( data );
registerToBatchFetchQueue( data );
}
}

if ( keyIsEager ) {
final Initializer<?> initializer = keyAssembler.getInitializer();
assert initializer != null;
Expand Down Expand Up @@ -233,6 +266,7 @@ public void initializeInstanceFromParent(Object parentInstance, Data data) {
: parentInstance;
// No need to initialize these fields
data.entityKey = null;
data.entityIdentifier = null;
data.setInstance( null );
if ( instance == null ) {
data.setState( State.MISSING );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,33 +207,50 @@ public void resolveInstance(Object instance, DiscriminatedEntityInitializerData
data.setInstance( null );
}
else {
final RowProcessingState rowProcessingState = data.getRowProcessingState();
final var rowProcessingState = data.getRowProcessingState();
final var session = rowProcessingState.getSession();
final LazyInitializer lazyInitializer = extractLazyInitializer( instance );
if ( lazyInitializer == null ) {
data.setState( State.INITIALIZED );
if ( keyIsEager ) {
final SharedSessionContractImplementor session = rowProcessingState.getSession();
data.concreteDescriptor = session.getEntityPersister( null, instance );
data.entityIdentifier = data.concreteDescriptor.getIdentifier( instance, session );
}
data.concreteDescriptor = session.getEntityPersister( null, instance );
data.entityIdentifier = data.concreteDescriptor.getIdentifier( instance, session );
}
else if ( lazyInitializer.isUninitialized() ) {
data.setState( eager ? State.RESOLVED : State.INITIALIZED );
if ( keyIsEager ) {
// Read the discriminator from the result set if necessary
final Object discriminatorValue = discriminatorValueAssembler.assemble( rowProcessingState );
data.concreteDescriptor = fetchedPart.resolveDiscriminatorValue( discriminatorValue ).getEntityPersister();
data.entityIdentifier = lazyInitializer.getInternalIdentifier();
}
// Read the discriminator from the result set if necessary
final Object discriminatorValue = discriminatorValueAssembler.assemble( rowProcessingState );
data.concreteDescriptor = fetchedPart.resolveDiscriminatorValue( discriminatorValue ).getEntityPersister();
data.entityIdentifier = lazyInitializer.getInternalIdentifier();
}
else {
data.setState( State.INITIALIZED );
if ( keyIsEager ) {
data.concreteDescriptor = rowProcessingState.getSession().getEntityPersister( null, lazyInitializer.getImplementation() );
data.entityIdentifier = lazyInitializer.getInternalIdentifier();
data.concreteDescriptor = session.getEntityPersister( null, lazyInitializer.getImplementation() );
data.entityIdentifier = lazyInitializer.getInternalIdentifier();
}


final var entityKey = new EntityKey( data.entityIdentifier, data.concreteDescriptor );
final var entityHolder = session.getPersistenceContextInternal().getEntityHolder(
entityKey
);

if ( entityHolder == null || entityHolder.getEntity() != instance && entityHolder.getProxy() != instance ) {
// the existing entity instance is detached or transient
if ( entityHolder != null ) {
final var managed = entityHolder.getManagedObject();
data.setInstance( managed );
data.entityIdentifier = entityHolder.getEntityKey().getIdentifier();
data.setState( !eager || entityHolder.isInitialized() ? State.INITIALIZED : State.RESOLVED );
}
else {
data.setState( State.RESOLVED );
initializeInstance( data );
}
}
data.setInstance( instance );
else {
data.setInstance( instance );
}

if ( keyIsEager ) {
final Initializer<?> initializer = keyValueAssembler.getInitializer();
assert initializer != null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,94 +174,102 @@ public void resolveInstance(EntityDelayedFetchInitializerData data) {
concreteDescriptor = entityPersister;
}

final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
if ( selectByUniqueKey ) {
final String uniqueKeyPropertyName = referencedModelPart.getReferencedPropertyName();
final Type uniqueKeyPropertyType = ( referencedModelPart.getReferencedPropertyName() == null ) ?
concreteDescriptor.getIdentifierType() :
session.getFactory().getRuntimeMetamodels()
.getReferencedPropertyType(
concreteDescriptor.getEntityName(),
uniqueKeyPropertyName
);

final EntityUniqueKey euk = new EntityUniqueKey(
concreteDescriptor.getEntityName(),
uniqueKeyPropertyName,
data.entityIdentifier,
uniqueKeyPropertyType,
session.getFactory()
);
Object instance = persistenceContext.getEntity( euk );
if ( instance == null ) {
// For unique-key mappings, we always use bytecode-laziness if possible,
// because we can't generate a proxy based on the unique key yet
if ( referencedModelPart.isLazy() ) {
instance = UNFETCHED_PROPERTY;
}
else {
// Try to load a PersistentAttributeInterceptable. If we get one, we can add the lazy
// field to the interceptor. If we don't get one, we load the entity by unique key.
PersistentAttributeInterceptable persistentAttributeInterceptable = null;
if ( getParent().isEntityInitializer() && isLazyByGraph( rowProcessingState ) ) {
final Object resolvedInstance =
getParent().asEntityInitializer().getResolvedInstance( rowProcessingState );
persistentAttributeInterceptable =
ManagedTypeHelper.asPersistentAttributeInterceptableOrNull( resolvedInstance );
}
initialize( data, null, concreteDescriptor );
}
}

if ( persistentAttributeInterceptable != null ) {
final LazyAttributeLoadingInterceptor persistentAttributeInterceptor = (LazyAttributeLoadingInterceptor) persistentAttributeInterceptable.$$_hibernate_getInterceptor();
persistentAttributeInterceptor.addLazyFieldByGraph( navigablePath.getLocalName() );
instance = UNFETCHED_PROPERTY;
}
else {
instance = concreteDescriptor.loadByUniqueKey(
uniqueKeyPropertyName,
data.entityIdentifier,
session
protected void initialize(EntityDelayedFetchInitializerData data, @Nullable EntityKey entityKey, EntityPersister concreteDescriptor) {
final RowProcessingState rowProcessingState = data.getRowProcessingState();
final SharedSessionContractImplementor session = rowProcessingState.getSession();
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
if ( selectByUniqueKey ) {
final String uniqueKeyPropertyName = referencedModelPart.getReferencedPropertyName();
final Type uniqueKeyPropertyType = ( referencedModelPart.getReferencedPropertyName() == null ) ?
concreteDescriptor.getIdentifierType() :
session.getFactory().getRuntimeMetamodels()
.getReferencedPropertyType(
concreteDescriptor.getEntityName(),
uniqueKeyPropertyName
);

// If the entity was not in the Persistence Context, but was found now,
// add it to the Persistence Context
if ( instance != null ) {
persistenceContext.addEntity( euk, instance );
}
final EntityUniqueKey euk = new EntityUniqueKey(
concreteDescriptor.getEntityName(),
uniqueKeyPropertyName,
data.entityIdentifier,
uniqueKeyPropertyType,
session.getFactory()
);
Object instance = persistenceContext.getEntity( euk );
if ( instance == null ) {
// For unique-key mappings, we always use bytecode-laziness if possible,
// because we can't generate a proxy based on the unique key yet
if ( referencedModelPart.isLazy() ) {
instance = UNFETCHED_PROPERTY;
}
else {
// Try to load a PersistentAttributeInterceptable. If we get one, we can add the lazy
// field to the interceptor. If we don't get one, we load the entity by unique key.
PersistentAttributeInterceptable persistentAttributeInterceptable = null;
if ( getParent().isEntityInitializer() && isLazyByGraph( rowProcessingState ) ) {
final Object resolvedInstance =
getParent().asEntityInitializer().getResolvedInstance( rowProcessingState );
persistentAttributeInterceptable =
ManagedTypeHelper.asPersistentAttributeInterceptableOrNull( resolvedInstance );
}

if ( persistentAttributeInterceptable != null ) {
final LazyAttributeLoadingInterceptor persistentAttributeInterceptor = (LazyAttributeLoadingInterceptor) persistentAttributeInterceptable.$$_hibernate_getInterceptor();
persistentAttributeInterceptor.addLazyFieldByGraph( navigablePath.getLocalName() );
instance = UNFETCHED_PROPERTY;
}
else {
instance = concreteDescriptor.loadByUniqueKey(
uniqueKeyPropertyName,
data.entityIdentifier,
session
);

// If the entity was not in the Persistence Context, but was found now,
// add it to the Persistence Context
if ( instance != null ) {
persistenceContext.addEntity( euk, instance );
}
}
}
if ( instance != null ) {
instance = persistenceContext.proxyFor( instance );
}
data.setInstance( instance );
}
if ( instance != null ) {
instance = persistenceContext.proxyFor( instance );
}
data.setInstance( instance );
}
else {
final EntityKey ek = entityKey == null ?
new EntityKey( data.entityIdentifier, concreteDescriptor ) :
entityKey;
final EntityHolder holder = persistenceContext.getEntityHolder( ek );
final Object instance;
if ( holder != null && holder.getEntity() != null ) {
instance = persistenceContext.proxyFor( holder, concreteDescriptor );
}
// For primary key based mappings we only use bytecode-laziness if the attribute is optional,
// because the non-optionality implies that it is safe to have a proxy
else if ( referencedModelPart.isOptional() && referencedModelPart.isLazy() ) {
instance = UNFETCHED_PROPERTY;
}
else {
final EntityKey entityKey = new EntityKey( data.entityIdentifier, concreteDescriptor );
final EntityHolder holder = persistenceContext.getEntityHolder( entityKey );
final Object instance;
if ( holder != null && holder.getEntity() != null ) {
instance = persistenceContext.proxyFor( holder, concreteDescriptor );
}
// For primary key based mappings we only use bytecode-laziness if the attribute is optional,
// because the non-optionality implies that it is safe to have a proxy
else if ( referencedModelPart.isOptional() && referencedModelPart.isLazy() ) {
instance = UNFETCHED_PROPERTY;
}
else {
instance = session.internalLoad(
concreteDescriptor.getEntityName(),
data.entityIdentifier,
false,
false
);

final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( instance );
if ( lazyInitializer != null ) {
lazyInitializer.setUnwrap( referencedModelPart.isUnwrapProxy() && concreteDescriptor.isInstrumented() );
}
instance = session.internalLoad(
concreteDescriptor.getEntityName(),
data.entityIdentifier,
false,
false
);

final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( instance );
if ( lazyInitializer != null ) {
lazyInitializer.setUnwrap( referencedModelPart.isUnwrapProxy() && concreteDescriptor.isInstrumented() );
}
data.setInstance( instance );
}
data.setInstance( instance );
}
}

Expand All @@ -287,9 +295,28 @@ public void resolveInstance(Object instance, EntityDelayedFetchInitializerData d
// This initializer is done initializing, since this is only invoked for delayed or select initializers
data.setState( State.INITIALIZED );
data.setInstance( instance );
final RowProcessingState rowProcessingState = data.getRowProcessingState();
final var rowProcessingState = data.getRowProcessingState();
final var session = rowProcessingState.getSession();
final var entityDescriptor = getEntityDescriptor();
data.entityIdentifier = entityDescriptor.getIdentifier( instance, session );

final var entityKey = new EntityKey( data.entityIdentifier, entityDescriptor );
final var entityHolder = session.getPersistenceContextInternal().getEntityHolder(
entityKey
);

if ( entityHolder == null || entityHolder.getEntity() != instance && entityHolder.getProxy() != instance ) {
// the existing entity instance is detached or transient
if ( entityHolder != null ) {
final var managed = entityHolder.getManagedObject();
data.entityIdentifier = entityHolder.getEntityKey().getIdentifier();
data.setInstance( managed );
}
else {
initialize( data, entityKey, entityDescriptor );
}
}
if ( keyIsEager ) {
data.entityIdentifier = getEntityDescriptor().getIdentifier( instance, rowProcessingState.getSession() );
final Initializer<?> initializer = identifierAssembler.getInitializer();
assert initializer != null;
initializer.resolveInstance( data.entityIdentifier, rowProcessingState );
Expand Down
Loading
Loading