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 @Override
public Object proxyFor(EntityHolder holder) throws HibernateException { 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(); 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 @Override

View File

@ -398,6 +398,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
this this
); );
isOwningInitializer = holder.getEntityInitializer() == this; isOwningInitializer = holder.getEntityInitializer() == this;
if ( entityInstance == null ) { if ( entityInstance == null ) {
resolveEntityInstance( rowProcessingState, holder, entityKey.getIdentifier() ); resolveEntityInstance( rowProcessingState, holder, entityKey.getIdentifier() );
} }
@ -527,6 +528,12 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
} }
this.isInitialized = true; 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 { else {
@ -754,13 +761,9 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
final PersistenceContext persistenceContext = session.getPersistenceContextInternal(); final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
if ( lazyInitializer != null ) { if ( lazyInitializer != null ) {
final EntityHolder holder = persistenceContext.getEntityHolder( entityKey ); final EntityHolder holder = persistenceContext.getEntityHolder( entityKey );
Object instance = holder.getEntity(); final Object instance = holder.getEntity();
if ( instance == null ) { assert instance != null : "The real entity instance must be resolved in the `resolveInstance()` phase";
instance = resolveInstance( if ( holder.getEntityInitializer() == this ) {
entityKey.getIdentifier(),
holder,
rowProcessingState
);
initializeEntity( instance, rowProcessingState ); initializeEntity( instance, rowProcessingState );
} }
lazyInitializer.setImplementation( instance ); lazyInitializer.setImplementation( instance );