Skip to content

Where is the best place to begin transaction using Hibernate in a tired web application with Struts 2?

I got this Java web application which uses Struts 2 and Hibernate. In the most upper layer comprises of the Struts 2 action classes. Then there are my business logic classes which are responsible for the logic of the application. Finally there is a DAO layer (called Database Bridge) which is responsible for communicating with the database.

Currently I open sessions and do the transactions in DAO layer like this:

public static void saveObject(Object object) throws Exception {
        Session session = null;

        try {
            session = HibernateUtil.getSessionFactory().getCurrentSession();
            session.beginTransaction();
            session.save(object);

            session.getTransaction().commit();

        } catch (Exception e) {
            session.getTransaction().rollback();
            e.printStackTrace();
            throw e;
        } finally {
            if (session != null)
                if (session.isOpen())
                    session.getTransaction().rollback();
        }
    }

There seems to be some problems with this approach:

  1. Logically my transactions are my Struts 2 actions (controllers) which should be either committed or rolled back. A Struts 2 action may lead to more than one DAO call, so it is possible that some parts of a logical transaction get committed and the rest of it get rolled back which hurts data integrity.

  2. Some objects contain some lazy collections. If we do the transactions in the DAO layer, we need to initialize those collections there which is not an efficient way. because we don’t need to load the collections in every action. So whenever an action needs a lazy collection we need to open a session in the action and load the lazy collection in there, which is a dirty solution.

I think it’s better to avoid doing the transactions in the DAO layer. If we place the transactions in the Struts 2 action they are treated as atomic transactions and data consistency will be maintained. on the other hand whenever we need a lazy collection we can initialize it inside the action.

In order to keep the code clean, I will keep the DAO layer the same as before, but the methods in the DAO will get the session as a parameter from the upper layer and they won’t deal with the commitment of transactions and sessions.

How does this strategy sound? is there any significant flaw in this approach? where do you think is the best place to start transactions and manage sessions?

Answer

It seems you are thinking in right direction but you should keep in mind that sessions in Hibernate are independent from transactions. Look at the transaction strategy configuration that could apply to your application.

Then you should read this article how the sessions and transactions work together. Lately you might follow the Generic DAO approach don’t know why but this technique is very popular.

And finally all of the above is already implemented by the Struts2 jQuery Grid. Look at this answer.

Seems all of the above are independent from Spring, if you like the Spring to manage transactions then you should go here.