Handling Hibernate Transactions

hibernate, jakarta-ee, java, transactions

Solution

I've run into this myself many times. Ordinarily my first recommendation would be Spring transaction management, however I understand you are trying to limit the number of third party libraries you are using.

Since you're using a static API in your HibernateUtil class, you may find it helpful to consolidate your logic in a method, and putting the 'what you want to do in a transaction' code (which varies controller to controller) in a callback.

First, define an interface to describe each controller's inTransaction behavior:

public interface TransactionCallback {
    void doInTransaction();
}

Now, create a static method in your HibernateUtil class to handle beginning, committing, and if necessary rolling back your transactions:

public class HibernateUtil {
    public static void inTransaction(TransactionCallback tc) {
        Transaction transaction = HibernateUtil.getSessionFactory().getCurrentSession().getTransaction();
        if (!HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().isActive()) {
            transaction.begin();
            try {
                tc.doInTransaction();
                transaction.commit();
            } catch (Exception e) {
                transaction.rollback();
            }
        }
    }
}

In your controller, you'd use your new method with an anonymous inner class:

....
    HibernateUtil.inTransaction(new TransactionCallback() {
        void doInTransaction() {
            // do stuff for this controller
        }
    });
....

This approach should at least take care of the duplication you'd like to eliminate, and there's plenty of room for extending it to handle particular exceptions, etc.

Problem

Currently I have this code duplicated in each one of my Controller methods: ``` Transaction transaction = HibernateUtil.getSessionFactory().getCurrentSession().getTransaction(); if (!HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().isActive()) { transaction.begin(); } ``` Is this the correct way or is there a better way of doing this, perhaps in a separate class that I can reference? If so, how? Every time I've tried to put it in a separate class and reference it from other classes, it failed. edit: I'm trying to use as few external libraries as possible. I wouldn't use Hibernate if Java had an ORM/JPA implementation built into the JDK

Original source