views:

17576

answers:

13

Hi all,

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)

I can post my DAO and annotation code if necessary. Please advise what else is needed.

TIA

Piko

+3  A: 

This generally means that the owning Hibernate session has already closed. You can do one of the following to fix it:

  1. whichever object creating this problem, use HibernateTemplate.initialize(object name)
  2. Use lazy=false in your hbm files.
digitalsanctum
Had the same problem and lazy=false fixed it. Thanks
mattRo55
lazy=false is not a solution unless you understand what implications it has.
pakore
+1  A: 

If you are managing the Hibernate session manually, you may want to look into sessionFactory.getCurrentSession() and associated docs here:

http://www.hibernate.org/hib_docs/v3/reference/en/html/architecture-current-session.html

cliff.meyers
+1  A: 

Okay, finally figured out where I was remiss. I was under the mistaken notion that I should wrap each DAO method in a transaction. Terribly wrong! I've learned my lesson. I've hauled all the transaction code from all the DAO methods and have set up transactions strictly at the application/manager layer. This has totally solved all my problems. Data is properly lazy loaded as I need it, wrapped up and closed down once I do the commit.

Life is goodly... :)

Piko
A: 

Hello Piko - Can you kindly explain how have you now moved transaction code from the DAO methods to the application/manager layer. I have my DAO methods implement 4 CRUD methods and each of these methods have try-catch inside which I have the session.beginTransaction(), commit() and rollback(). I am facing the same problem as you faced however, I also believe that lazy=false may not be appropriate solution. Please explain how can I solve it like you did?

Vikasmlb
A: 

I really need help on this one.. Can anyone understand what Piko means in his response?

Vikasmlb
+1  A: 

I think Piko means in his response that there is the hbm file. I have a file called Tax.java. The mapping information are saved in the hbm (=hibernate mapping) file. In the class tag there is a property called lazy. Set that property to true. The following hbm example shows a way to set the lazy property to false.

` id ...'

If you are using Annotations instead look in the hibernate documenation. http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/

I hope that helped.

Alexander Fenske
+1  A: 

if you are using Lazy loading your method must be annotated with @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) for Stateless Session EJB

Rolando Quezada
A: 

We encountered this error as well. What we did to solve the issue is we added a lazy=false in the Hibernate mapping file.

It appears we had a class A that's inside a Session that loads another class B. We are trying to access the data on class B but this class B is detached from the session.

In order for us to access this Class B, we had to specify in the class A's Hibernate mapping file the lazy=false attribute. For example,

     <many-to-one name="classA" 
                 class="classB"
                 lazy="false">
        <column name="classb_id"
                sql-type="bigint(10)" 
                not-null="true"/>
    </many-to-one>  
chris
A: 

Thank you very much. putting lazy=false in hbm.xml file resolved my issue too :) cheers.

Seshagiri
+1  A: 

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.

pakore
you mean lazy=false, right ?
Antoine Claval
Yes, sorry. I'll correct it.
pakore
+1  A: 

If you are using hibernate with JPA annotations this will be use full. in your service class there should be a setter for entity manager with @PersistenceContext. change this to @PersistenceContext(type = PersistenceContextType.EXTENDED). Then you can access lazy property in any where.

konda