From cd81b337bc5a5e56b01551da5fa849e8898a93a1 Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Tue, 14 Nov 2023 11:59:27 +0100 Subject: [PATCH] HHH-17408 Unproxying leads to uninitialized one-to-one associations in some cases involving polymorphism --- .../internal/StatefulPersistenceContext.java | 10 +++------- .../graph/entity/AbstractEntityInitializer.java | 17 ++++++++++------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java index 9781c46e5c..0ed803d56c 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java @@ -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 diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityInitializer.java index d0e407821e..4ee090ffde 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityInitializer.java @@ -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 );