Hibernate Transaction Management Tutorial


In this tutorial, we will learn how to manage transactions in Hibernate applications. Let's first familiar with few transactions related concepts.
Before get started check out  Hibernate Developer Guide and Spring Hibernate Tutorials to develop J2EE enterprise applications.

What is a transaction?

A transaction simply represents a unit of work. Generally speaking, if you wrap your work in a transaction, the behavior of other system users will not affect your data. A transaction can be started, committed to writing data to the database, or rolled back to remove all changes from the beginning onward (usually as the result of an error). To properly complete an operation, you obtain a Transaction object from the database (beginning the transaction) and manipulate the session as shown in the following code:

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

Let's discuss what are ACID properties in detail.

ACID Properties

Atomicity: A transaction should be all or nothing. If it fails to complete, the database will be left as if none of the operations had ever been performed—this is known as a rollback.

Consistency: A transaction should be incapable of breaking any rules defined for the database. For example, foreign keys must be obeyed. If for some reason this is impossible, the transaction will be rolled back.

Isolation: The effects of the transaction will be completely invisible to all other transactions until it has completed successfully. This guarantees that the transaction will always see the data in a sensible state.

Durability: The data should be retained intact. If the system fails for any reason, it should always be possible to retrieve the database up to the moment of the failure. 

Transaction Interface

In the hibernate framework, we have 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 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 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 Student JPA entity, let's persist 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();
            }
        }
    }

Consider we have Student JPA entity, let's update 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 student where id = 1;

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 student record from a database.

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, what are ACID properties, we have also seen briefly about Transaction interface and finally, we have seen how to manage transactions in hibernate application with code snippets.
You can learn more about Hibernate framework here at Hibernate ORM Tutorial

GitHub Repository

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

References

Hibernate ORM 5.4.0.Final User Guide

Comments