HHH-17408 Unproxying leads to uninitialized one-to-one associations in some cases involving polymorphism

This commit is contained in:
Andrea Boriero 2023-11-14 11:59:27 +01:00 committed by Christian Beikov
parent f00c57d629
commit cd81b337bc
2 changed files with 13 additions and 14 deletions

View File

@ -895,14 +895,10 @@ public class StatefulPersistenceContext implements PersistenceContext {
@Override
public Object proxyFor(EntityHolder holder) throws HibernateException {
final Object entity = holder.getEntity();
final EntityEntry e = getEntry( entity );
final EntityPersister persister;
if ( e == null || !( persister = e.getPersister() ).hasProxy() ) {
return entity;
}
final Object proxy = holder.getProxy();
return proxy != null? narrowProxy( proxy, persister, e.getEntityKey(), entity ) : entity;
return proxy != null && holder.getDescriptor().hasProxy()
? narrowProxy( proxy, holder.getDescriptor(), holder.getEntityKey(), holder.getEntity() )
: holder.getEntity();
}
@Override

View File

@ -398,6 +398,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
this
);
isOwningInitializer = holder.getEntityInitializer() == this;
if ( entityInstance == null ) {
resolveEntityInstance( rowProcessingState, holder, entityKey.getIdentifier() );
}
@ -527,6 +528,12 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
}
this.isInitialized = true;
}
else if ( isOwningInitializer ) {
// Resolve the real entity instance for this proxy early so that potentially nested calls
// for eager association loading can leverage the real instance if needed
assert holder.getEntity() == null;
resolveEntityInstance( entityIdentifier, rowProcessingState );
}
}
}
else {
@ -754,13 +761,9 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
if ( lazyInitializer != null ) {
final EntityHolder holder = persistenceContext.getEntityHolder( entityKey );
Object instance = holder.getEntity();
if ( instance == null ) {
instance = resolveInstance(
entityKey.getIdentifier(),
holder,
rowProcessingState
);
final Object instance = holder.getEntity();
assert instance != null : "The real entity instance must be resolved in the `resolveInstance()` phase";
if ( holder.getEntityInitializer() == this ) {
initializeEntity( instance, rowProcessingState );
}
lazyInitializer.setImplementation( instance );