hibernate: LazyInitializationException: could not initialize proxy

Piko picture Piko · Dec 6, 2008 · Viewed 204.6k times · Source

Here's one that has me perplexed. I'm trying to implement a basic Hibernate DAO structure, but am having a problem.

Here's the essential code:

int startingCount = sfdao.count();
sfdao.create( sf );
SecurityFiling sf2 = sfdao.read( sf.getId() );
sfdao.delete( sf );
int endingCount = sfdao.count();

assertTrue( startingCount == endingCount );
assertTrue( sf.getId().longValue() == sf2.getId().longValue() );
assertTrue( sf.getSfSubmissionType().equals( sf2.getSfSubmissionType() ) );
assertTrue( sf.getSfTransactionNumber().equals( sf2.getSfTransactionNumber() ) );

It fails on the third assertTrue where it's trying to compare a value in sf to the corresponding value in sf2. Here's the exception:

org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:86)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:140)
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
    at com.freightgate.domain.SecurityFiling_$$_javassist_7.getSfSubmissionType(SecurityFiling_$$_javassist_7.java)
    at com.freightgate.dao.SecurityFilingTest.test(SecurityFilingTest.java:73)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:40)

Answer

pakore picture pakore · Sep 3, 2010

The problem is that you are trying to access a collection in an object that is detached. You need to re-attach the object before accessing the collection to the current session. You can do that through

session.update(object);

Using lazy=false is not a good solution because you are throwing away the Lazy Initialization feature of hibernate. When lazy=false, the collection is loaded in memory at the same time that the object is requested. This means that if we have a collection with 1000 items, they all will be loaded in memory, despite we are going to access them or not. And this is not good.

Please read this article where it explains the problem, the possible solutions and why is implemented this way. Also, to understand Sessions and Transactions you must read this other article.