Hibernate and the famous LazyInitializationException

When you are working with Hibernate there is a big chance you have (or will) run into the lazy loading exception: org.hibernate.LazyInitializationException: failed to lazily initialize a collection – no session or session was closed. Well, last week it was my turn. Luckiliy there are lots and lots of articles and blogs about it on the net so in a short time you will have enough information about it to fill at least a day or two by reading them.
In our case we had in one of our objects a OneToMany relation with a child object and it’s fetchType was set to EAGER. Now this doesn’t have to be a bad choice but in our case it wasn’t always necessary to collect the children when the parent was created. So I just set the fetchType to LAZY and tested it… And there it was: the LazyinitializationException.
So apparently we were trying to load the Object children while there was no (Hibernate) session anymore to which the parent object was attached. After a short search it appeared that the cause of this problem lay in the Transaction demarcation we had defined in Spring (we are using the combination Spring-Hiberate in our project).
We have a ‘classic’ layer structure in our components going from business layer -> service layer -> dao layer. Now we had transactions defined at both business layer and service layer. This caused that some objects were created in one transaction, that transaction ended also ending the Hibernate session, and then the object was used, so it tried to lazy load its children but without a Hibernate session…. et voila: the lazy loading exception. So we did a redesign of our transaction demarcation and this time we only started and ended transactions in our business layer: the correct place according to us. This made the transactional behaviour much more clear but also lead to another problem.
A lot of our unit-test cases are testing at the service layer level. Some of them were failing now since there was no transaction defined at this level. So we decided to make each test method runnning in its own transaction. But we didn’t want to have to declare all our test classes in the Spring context. So we made a base test class that sets the transactions programmatically. To have this working with TestNG 5.0 we made the following base class:

import net.pascalalma.util.MyContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.orm.hibernate3.HibernateTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;

 * Use this class as base class for your test if you need transactional context
 * in your tests. If this is not needed you should use CoreTest as base class.
 * A transactional is started before the test-method is ran and the transaction will
 * be rolled back when the test method has finished. If you need the data to be committed
 * to the database you can call 'setComplete()'. This will perform a commit on the
 * current transaction.
 * @author Pascal Alma
public class TransactionalCoreTest {

   private static final Log LOG = LogFactory.getLog(TransactionalCoreTest.class);

   private HibernateTransactionManager mgr = null;
   private TransactionStatus status = null;

    * Starts a transaction.
   protected void setUp() {
      // Obtaining the Spring context
      ClassPathXmlApplicationContext ctx = MyContext.getContext();
      // Set the transactionManager
      mgr = (HibernateTransactionManager) ctx.getBean("transactionManager");
      // Start the transaction
      status = mgr.getTransaction(new DefaultTransactionDefinition());

      LOG.debug("Transaction started");

    * Commits the changes in the current transaction. At default changes are lost as the
    * transaction is rolled back at the end of the testcase.
   protected void setComplete() {
      if (!status.isCompleted()) {

    * Ends the current transaction by rolling back the changes (if any).
   protected void tearDown() {
      if (!status.isCompleted()) {
      LOG.debug("Transaction ended");

So, if we have a test class that needs transactional behaviour we extend from this base class. If we are testing at business layer level, we extend a test base class without this transactional behaviour. This is working fine for us for now, but if you think your solution is better, please let me know! I am always willing to learn new things, especially if these thing are better then the ones I know 🙂


About Pascal Alma

Pascal is a senior IT consultant and has been working in IT since 1997. He is monitoring the latest development in new technologies (Mobile, Cloud, Big Data) closely and particularly interested in Java open source tool stacks, cloud related technologies like AWS and mobile development like building iOS apps with Swift. Specialties: Java/JEE/Spring Amazon AWS API/REST Big Data Continuous Delivery Swift/iOS
This entry was posted in Hibernate and tagged . Bookmark the permalink.

2 Responses to Hibernate and the famous LazyInitializationException

  1. nikhil says:

    Hi there,

    Nice article although didn’t solve my problem 😉 I’ve the same situation as you have but I’m still without any soln. I’ve no problem regarding the TestCases as I have a ‘setup’ which can help me there.

    sessionFactory = (SessionFactory) beanFactory.getBean(“sessionFactory”);
    Session session = SessionFactoryUtils.getSession(sessionFactory, true);
    TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));

    This essentially keeps the hibernate session open till the testCase executes… so no problem there… The problem appears when I deploy my application in Tomcat. Somehow even specifying the following in my applicationContext-aop.xml has not proved to be 100% successful.

    <aop:pointcut id=”serviceMethods”
    expression=”execution(*c.*.*(..))” />

    Do you face this problem when you start you app in the app server? If yes, then how did you solve it…I would really appreciate if you can help me out as I’m stuck here for quite some time now.


  2. nikhil says:

    somehow…config didn’t appear after posting the comment

    <aop:pointcut id=”serviceMethods” expression=”execution(*c.*.*(..))” />

Comments are closed.