From 46c9da1a46ea8f2bd5bae16fe7fc4c17a049dc23 Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Mon, 20 Feb 2023 20:11:29 +0100 Subject: [PATCH] HHH-16193 LazyInitializationException when accessing loaded reference after session is closed using bytecode enhancement --- .../internal/DefaultLoadEventListener.java | 16 +++++++++++++++- ...InitializeEntitySelectFetchInitializer.java | 18 ++++++++---------- .../internal/EntitySelectFetchInitializer.java | 10 ---------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java index f69401bf25..43ce4bfe60 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java @@ -12,11 +12,13 @@ import org.hibernate.NonUniqueObjectException; import org.hibernate.PersistentObjectException; import org.hibernate.TypeMismatchException; import org.hibernate.action.internal.DelayedPostInsertIdentifier; +import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor; import org.hibernate.cache.spi.access.EntityDataAccess; import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.PersistentAttributeInterceptable; +import org.hibernate.engine.spi.PersistentAttributeInterceptor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.event.spi.EventSource; import org.hibernate.event.spi.LoadEvent; @@ -38,6 +40,9 @@ import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.LazyInitializer; import org.hibernate.stat.spi.StatisticsImplementor; +import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable; +import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable; + /** * Defines the default load event listeners used by hibernate for loading entities * in response to generated load events. @@ -530,7 +535,16 @@ public class DefaultLoadEventListener implements LoadEventListener { = CacheEntityLoaderHelper.INSTANCE.loadFromSessionCache( event, keyToLoad, options ); final Object entity = persistenceContextEntry.getEntity(); if ( entity != null ) { - return persistenceContextEntry.isManaged() ? entity : null; + if ( persistenceContextEntry.isManaged() ) { + if ( isPersistentAttributeInterceptable( entity ) ) { + final PersistentAttributeInterceptor interceptor = asPersistentAttributeInterceptable( entity ).$$_hibernate_getInterceptor(); + if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) { + ( (EnhancementAsProxyLazinessInterceptor) interceptor ).forceInitialize( entity, null ); + } + } + return entity; + } + return null; } else { return load( event, persister, keyToLoad ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchInitializeEntitySelectFetchInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchInitializeEntitySelectFetchInitializer.java index 7baaf8c7cf..e35f4f4cec 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchInitializeEntitySelectFetchInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchInitializeEntitySelectFetchInitializer.java @@ -70,16 +70,14 @@ public class BatchInitializeEntitySelectFetchInitializer extends AbstractBatchEn entityInstance = loadingEntityEntry.getEntityInstance(); } else { - if ( entityInstance == null ) { - // Force creating a proxy - entityInstance = session.internalLoad( - entityKey.getEntityName(), - entityKey.getIdentifier(), - false, - false - ); - toBatchLoad.add( entityKey ); - } + // Force creating a proxy + entityInstance = session.internalLoad( + entityKey.getEntityName(), + entityKey.getIdentifier(), + false, + false + ); + toBatchLoad.add( entityKey ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntitySelectFetchInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntitySelectFetchInitializer.java index c9ac022285..683d7a6040 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntitySelectFetchInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntitySelectFetchInitializer.java @@ -10,10 +10,8 @@ import java.util.function.Consumer; import org.hibernate.FetchNotFoundException; import org.hibernate.annotations.NotFoundAction; -import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.PersistenceContext; -import org.hibernate.engine.spi.PersistentAttributeInterceptor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.log.LoggingHelper; import org.hibernate.internal.util.StringHelper; @@ -33,8 +31,6 @@ import org.hibernate.sql.results.graph.entity.EntityLoadingLogging; import org.hibernate.sql.results.graph.entity.LoadingEntityEntry; import org.hibernate.sql.results.jdbc.spi.RowProcessingState; -import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable; -import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable; import static org.hibernate.internal.log.LoggingHelper.toLoggableString; /** @@ -138,12 +134,6 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl final PersistenceContext persistenceContext = session.getPersistenceContextInternal(); entityInstance = persistenceContext.getEntity( entityKey ); if ( entityInstance != null ) { - if ( isPersistentAttributeInterceptable( entityInstance ) ) { - final PersistentAttributeInterceptor interceptor = asPersistentAttributeInterceptable( entityInstance ).$$_hibernate_getInterceptor(); - if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) { - ( (EnhancementAsProxyLazinessInterceptor) interceptor ).forceInitialize( entityInstance, null ); - } - } isInitialized = true; return; }