Hibernate Transaction Management Tutorial

In this tutorial, we will learn how to manage transactions in Hibernate CRUD Applications. 


Let's first familiarize ourselves with a few transaction-related concepts.

What is a transaction? 

A transaction simply represents a unit of work. Generally speaking, a transaction is a set of SQL operations that need to be either executed successfully or not at all. 

A transaction can be described by ACID properties (Atomicity, Consistency, Isolation, and Durability).

Let's discuss what are ACID properties in detail.

ACID Properties

A database must satisfy the ACID properties (Atomicity, Consistency, Isolation, and Durability) to guarantee the success of a database transaction.

1. Atomicity: Each transaction should be carried out in its entirety; if one part of the transaction fails, then the whole transaction fails.

2. Consistency: The database should be in a valid state before and after the performed transaction.

3. Isolation: Each transaction should execute in complete isolation without knowing the existence of other transactions.

4. Durability: Once the transaction is complete, the changes made by the transaction are permanent (even in the occurrence of unusual events such as power loss).

Transaction Interface 

In the hibernate framework, we have a Transaction interface that defines the unit of work. It maintains abstraction from the transaction implementation (JTA, JDBC).

A transaction is associated with Session and instantiated by calling session.beginTransaction().

The methods of the Transaction interface are as follows:
  • void begin() - starts a new transaction.
  • void commit()  - ends the unit of work unless we are in FlushMode.NEVER.
  • void rollback()  - forces this transaction to rollback.
  • void setTimeout(int seconds) - it sets a transaction timeout for any transaction started by a subsequent call to begin on this instance.
  • boolean isAlive()  - checks if the transaction is still alive.
  • void registerSynchronization(Synchronization s)  - registers a user synchronization callback for this transaction.
  • boolean wasCommited()  - checks if the transaction is committed successfully.
  • boolean wasRolledBack() - checks if the transaction is rolled back successfully.
Read more about the Transaction interface at Hibernate API Java doc.

HibernateTransaction Management CRUD Example

The below CRUD source code snippet demonstrates the usage of Transactions in Hibernate applications.

Consider, we have a Student JPA entity:
@Entity
@Table(name = "student")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "email")
    private String email;

   // getter/setter
}
Let's persist the student object within a transaction.
public void insertStudent() {
        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            // start a transaction
            transaction = session.beginTransaction();

            String hql = "INSERT INTO Student (firstName, lastName, email) " +
                "SELECT firstName, lastName, email FROM Student";
            Query query = session.createQuery(hql);
            int result = query.executeUpdate();
            System.out.println("Rows affected: " + result);

            // commit transaction
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
        }
    }
Let's update the student object within a transaction:
    public void updateStudent(Student student) {
        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            // start a transaction
            transaction = session.beginTransaction();

            // save the student object
            String hql = "UPDATE Student set firstName = :firstName " + "WHERE id = :studentId";
            Query query = session.createQuery(hql);
            query.setParameter("firstName", student.getFirstName());
            query.setParameter("studentId", 1);
            int result = query.executeUpdate();
            System.out.println("Rows affected: " + result);

            // commit transaction
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
        }
    }
Let's delete the student object within a transaction:
public void deleteStudent(int id) {

        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            // start a transaction
            transaction = session.beginTransaction();

            // Delete a student object
            Student student = session.get(Student.class, id);
            if (student != null) {
                String hql = "DELETE FROM Student " + "WHERE id = :studentId";
                Query query = session.createQuery(hql);
                query.setParameter("studentId", id);
                int result = query.executeUpdate();
                System.out.println("Rows affected: " + result);
            }

            // commit transaction
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
        }
    }
Let's get the student object within a transaction:
public Student getStudent(int id) {

        Transaction transaction = null;
        Student student = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            // start a transaction
            transaction = session.beginTransaction();

            // get an student object
            String hql = " FROM Student S WHERE S.id = :studentId";
            Query query = session.createQuery(hql);
            query.setParameter("studentId", id);
            List results = query.getResultList();

            if (results != null && !results.isEmpty()) {
                student = (Student) results.get(0);
            }
            // commit transaction
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
        }
        return student;
    }

Conclusion

We have seen what is a transaction, and what are ACID properties, we have also seen a brief about the Transaction interface and finally, we have seen how to manage transactions in Hibernate applications with CRUD code snippets.
You can learn more about Hibernate framework here at Hibernate ORM Tutorial

GitHub Repository

The complete source code of this article is available on my GitHub Repository - https://github.com/RameshMF/Hibernate-ORM-Tutorials

Comments