Bug 1124935 - [GSS](6.4.0) 'LazyInitializationException: could not initialize proxy - no Session' during attribute access
Summary: [GSS](6.4.0) 'LazyInitializationException: could not initialize proxy - no Se...
Alias: None
Product: JBoss Enterprise Application Platform 6
Classification: JBoss
Component: Hibernate
Version: 6.2.3
Hardware: Unspecified
OS: Unspecified
Target Milestone: ---
: ---
Assignee: Gail Badner
QA Contact: Martin Simka
Russell Dickenson
Depends On:
TreeView+ depends on / blocked
Reported: 2014-07-30 16:27 UTC by Stephen Fikes
Modified: 2018-12-06 17:32 UTC (History)
2 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Last Closed: 2014-08-06 21:44:45 UTC
Type: Bug

Attachments (Terms of Use)
Testcase (4.97 KB, application/zip)
2014-07-30 16:30 UTC, Stephen Fikes
no flags Details
Annotated test case showing expected behavior (13.78 KB, text/x-java-source)
2014-08-06 21:42 UTC, Gail Badner
no flags Details

Description Stephen Fikes 2014-07-30 16:27:24 UTC
Description of problem:
When a detached instance is merged/updated and its associations are navigated, 'LazyInitializationException: could not initialize proxy - no Session' is raised while accessing a property for an associated entity

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1. Create instances of three classes where TestClass1 has one associated TestClass2 instance and the TestClass2 instance has one associated TestClass3 instance
2. In a new session load TestClass1 by ID, navigate to TestClass2 then close the session
3. In a new session, update/merge TestClass1 from step 2, re-retrieve the updated/merged TestClass1 from the session by ID, navigate the associations to the TestClass3 entity and access one of its properties

Actual results:
The following exception is raised:

org.hibernate.LazyInitializationException: could not initialize proxy - no Session
        at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164)
        at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285)
        at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
        at TestClass3_$$_jvstaf8_2.getName(TestClass3_$$_jvstaf8_2.java)
        at Test1.test(Test1.java:50)

Expected results:
The attribute access is expected to be successful

Additional info:
Testcase (see pom.xml) is for:
            <version>4.2.7.SP4-redhat-1</version> <!-- EAP 6.2.3 -->

Testcase also verified with both of the following:
            <!-- <version>4.2.7.SP5-redhat-1</version> -->  <!-- EAP 6.2.4 -->
            <!-- <version>4.3.5.Final</version> -->

Comment 1 Stephen Fikes 2014-07-30 16:30:29 UTC
Created attachment 922644 [details]

Comment 2 Gail Badner 2014-08-06 21:32:12 UTC
his is not a bug.

When Session.update( testClass1 ) is executed:

If testClass1.testClass2 is not initialized, the uninitialized proxy is reattached to the Session; this happens regardless of whether the update operation is cascaded to the association. Hibernate does this because it is safe to do. Hibernate knows that the association has not been updated (because it is unitialized). Since the session contains the proxy it can safely be initialized later (in the same session).

If testClass1.testClass2 is initialized, the initialized proxy is reattached to the Session only if the update operation is cascaded to the associaton. When the update operation is not cascaded to the association, it is not safe for Hibernate to reattach proxy because Hibernate has no way of knowing if the initialized proxy state has been updated by the application; reattaching an initialized proxy would implicitly cascade the update operation to the association. 

In the test case, testClass1.testClass2 is not reattached to the Session, so testClass1.testClass2.testClass3 also will not be attached to the Session. When the test tries to initialize the proxy, Hibernate will throw LazyInitializationException because the proxy  (testClass1.testClass2.testClass3) is not attached to the Session.

There are 2 ways to deal with this:
1) configure @org.hibernate.annotations.Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE}) for the lazy association
2) call Session.update( testClass1.testClass2 ) to reattach the testClass1.testClass2; if testClass1.testClass2.testClass3 is uninitialized, it will also be attached to the Session; then it will be safe to initialize testClass1.testClass2.testClass3.

When Session.merge( testClass1 ) is executed, and the merge operation is not cascaded the association, the state from testClass1.testClass2 is ignored. It does not matter whether testClass1.testClass2 has already been initialized. The merge result will contain an uninitialized proxy for the lazy association.

Comment 3 Gail Badner 2014-08-06 21:42:11 UTC
Created attachment 924621 [details]
Annotated test case showing expected behavior

Note You need to log in before you can comment on or make changes to this bug.