Transaction handling – default pattern

I have explained before that if you call the Hibernate session, you have to handle exceptions. You don’t have to code the exception handling everywhere. The Struts Integration in chapter Hibernate and Struts the section called “Hibernate and Struts” example shows how to do this in a single place. In the following, I will show you all of the required steps.

Default pattern for transaction/exception handling. 

SessionFactory factory = InitSessionFactory.getInstance();
Session session = factory.openSession();
Transaction tx = null;
try {
   tx = session.beginTransaction();
   // do some work
   tx.commit();
   } catch (RuntimeException e) {
      try {
         if (tx != null)
            tx.rollback();
      } catch (HibernateException e1) {
      log.error("Transaction roleback not succesful");
   }
   throw e;
} finally {
   session.close();
}

We open a session, then we start a transaction calling session.beginTransaction. The transaction is automatically bound to the session. If we get no exception then we call tx.commit to commit the transaction. Before Hibernate sends the commit to the database it will call flush internally to synchronize the persistence context with the database. All open insert/delete/update statements will be sent to the database.

If we get an exception, the Hibernate session becomes inconsistent. We must close it. In the code above, this is ensured with the finally block.

In order to prevent a transaction leak in the database we must rollback the transaction. This is done calling tx.rollBack. Imagine your database is unavailable. The rollback may fail as well, this is the reason why I wrapped it into another try-catch block. After this we throw the first exception again.

We can simplify the pattern but I wanted to explain all requirements we have to implement first.

Your responsibilities when using Hibernate