LazyInitializationException: could not initialize proxy - the owning Session was closed

Description

I noticed the issue in our system when trying to migrate to the latest version. In some scenarios, we start to receive

.

I looked into the issue and found that the behavior changed in version 5.2.2 and related to the fix created for issue - Session not flushing starting from 5.2.0 in Karaf + Arie and particularly in the commit https://github.com/hibernate/hibernate-orm/commit/109410b153f8e15ab3de3e99cb9924a085fe3a0f SessionImpl.java

The lazy loading is broken for the following scenario. Suppose we have 2 classes
class A {
// lazy loaded
List<B> itemsB;
}
class B {
// lazy loaded
List<C> itemsC;
}
In our application we using extended persistent context and set "hibernate.enable_lazy_load_no_trans" flag to true;

In request 1 we load an instance of class A and save the reference to the loaded instance in the memory. The instance of class A has itemsB lazy initialized.
In request 2 we trying to access itemsB property from the instance A loaded in the first request. As the session where A was loaded already closed (and set to null) Hibernate creates a temp session to load itemsB.Once they loaded the temp session is closed by hibernate. Afterwards, in the same request, we trying to iterate over itemsC for instance of B. The ItemsC is lazy loaded collection and it has a link to the session and because the session used to load itemsB already closed we have the exception.

Previously, for all session, before the session is closed it will be removed from all lazyloaded collections so the collection then could be loaded with a new session. However, as part of changes in SessionImpl.class this is not true anymore. When session closing while the transaction is active, or in my case for temp session the session is not unset for lazy loaded collections.

Environment

JPA/JTA EXTENDED, UNSYNCHRONIZED persistent context
hibernate.enable_lazy_load_no_trans=true;

Activity

Show:
Markus Lutum
October 31, 2019, 11:25 AM

I just want to mention that after migrating our appserver from Wildfly 13 to 18 (with Hibernate 5.3.12) I see exactly the same issue.

I have a more complex model but actually the same happens. We have enable_lazy_load_no_trans enabled. While creating a proxy the ByteBuddyInterceptor sets the session. But the instance is not initialized! Then the temporary session is closed. In a later call the same object is initialized (ByteBuddyInterceptor(AbstractLazyInitializer).getImplementation() … initialize() and this proxy is still assigned to the closed session.

This only happens if the entity(proxy) was created already somewhere else as a lazy reference. But in this call I do not initialize this proxy.

 

Markus Lutum
November 18, 2019, 11:52 AM

I was able to reproduce this in a testcase. See Pull Request:

Andrea Boriero
November 18, 2019, 1:17 PM

Hi ,

thanks a lot for the reproducer.

Markus Lutum
November 19, 2019, 12:31 PM

By the way…. If I add

 

to my persistence.xml it seams to solve the problems. At least all our integration tests are green then.

I am just scared a bit on side effects because of the Javadoc:

“Whether or not discard persistent context on entityManager.close() The EJB3 compliant and default choice is false”

 

Andrea Boriero
March 24, 2020, 12:42 PM
Edited

The problem seems solved in 5.4 I have created with a solution for the issue.

 

Assignee

Andrea Boriero

Reporter

Mikhail Chibel

Fix versions

None

Labels

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Worked in

5.2.1

Components

Affects versions

Priority

Critical
Configure