Docs Menu
Docs Home
/ /

Transactions and Sessions

In this guide, you can learn how to use the MongoDB Extension for Hibernate ORM to perform transactions. Transactions allow you to run a series of operations that change data only if the entire transaction is committed.

In MongoDB, transactions run within logical sessions. A session is a grouping of related read or write operations that you want to run sequentially. Sessions enable causal consistency for a group of operations and allow you to run operations in an ACID-compliant transaction, which is a transaction that meets an expectation of atomicity, consistency, isolation, and durability.

The Hibernate ORM extension supports the following APIs for managing sessions and transactions:

  • Hibernate Session: Allows you to use the org.hibernate.Transaction API to group your database operations. To learn more, see Hibernate Transaction API in the Hibernate ORM user guide.

  • Jakarta Persistence EntityManager: Instructs the Hibernate ORM to manage a Session internally and allows you to use the jakarta.persistence.EntityTransaction API to group your database operations. To learn more, see the jakarta.persistence package in the Jakarta EE documentation.

The examples in this guide use the Movie entity, which represents the sample_mflix.movies collection from the Atlas sample datasets. The Movie entity has the following definition:

import com.mongodb.hibernate.annotations.ObjectIdGenerator;
import org.bson.types.ObjectId;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name = "movies")
public class Movie {
@Id
@ObjectIdGenerator
private ObjectId id;
private String title;
private String plot;
private int year;
private String[] cast;
public Movie(String title, String plot, int year, String[] cast) {
this.title = title;
this.plot = plot;
this.year = year;
this.cast = cast;
}
public Movie() {
}
public ObjectId getId() {
return id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPlot() {
return plot;
}
public void setPlot(String plot) {
this.plot = plot;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public String[] getCast() {
return cast;
}
public void setCast(String[] cast) {
this.cast = cast;
}
}

To learn how to create a Java application that uses the MongoDB Extension for Hibernate ORM to interact with this MongoDB sample collection, see the Get Started tutorial.

To interact with MongoDB data, you must run all database operations in a session. This section shows how to manage a database session in the following ways:

Tip

Before using a Session, you must create a HibernateUtil.java file that configures a SessionFactory. To learn more, see the Configure your Application step of the Get Started tutorial.

To start a Hibernate Session, perform the following steps:

  1. Retrieve a SessionFactory from your HibernateUtil utility class by using the getSessionFactory() method. The SessionFactory stores your MongoDB connection configuration and can open new database sessions.

  2. Create a Session by calling the openSession() method on your SessionFactory instance.

  3. After running database operations, close your SessionFactory and Session by using the close() method on both instances.

The following example runs a database query in a session and retrieves a document that has a title value of "Erin Brockovich" from the sample_mflix.movies collection:

var sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
var movie = session.createQuery("from Movie where title = :t", Movie.class)
.setParameter("t", "Erin Brockovich")
.getSingleResult();
System.out.println("Title: " + movie.getTitle() + ", Year: " + movie.getYear());
session.close();
sf.close();
Title: Erin Brockovich, Year: 2000

You can also use Java's try-with-resources statement to simplify the session management logic and automatically close the session, as shown in the following code:

var sf = HibernateUtil.getSessionFactory();
try (Session session = sf.openSession()) {
var movie = session.createQuery("from Movie where title = :t", Movie.class)
.setParameter("t", "Erin Brockovich")
.getSingleResult();
System.out.println("Title: " + movie.getTitle() + ", Year: " + movie.getYear());
}
sf.close();

Tip

Before using an EntityManager, you must create a persistence.xml file that declares a persistence unit. To learn more, see the Tutorial using JPA-standard APIs in the Hibernate ORM documentation.

To start a Jakarta Persistence API (JPA) EntityManager, perform the following steps:

  1. Create an EntityManagerFactory from your persistence.xml file by calling the createEntityManagerFactory() method, which creates a SessionFactory internally.

  2. Create an EntityManager by calling the createEntityManager() method on your EntityManagerFactory instance, which creates a Session internally.

  3. After running database operations, close your EntityManagerFactory and EntityManager by calling the close() method on both instances.

The following example runs a database query in an entity manager and retrieves documents that have a year value of 1929 from the sample_mflix.movies collection:

// Replace <persistence unit> with the name of your persistence unit in the persistence.xml file
EntityManagerFactory emf = Persistence.createEntityManagerFactory("<persistence unit>");
EntityManager entityManager = emf.createEntityManager();
var results = entityManager.createQuery("select m from Movie m where m.year = :y", Movie.class)
.setParameter("y", 1929)
.getResultList();
results.forEach(movie -> System.out.println(movie.getTitle()));
entityManager.close();
emf.close();
The Broadway Melody
Queen Kelly
Asphalt
Hallelujah
Disraeli
Applause
Lambchops

In Jakarta Persistence v3.1 or later, you can use Java's try-with-resources statement to automatically close the EntityManager, as shown in the Hibernate Session section.

To modify MongoDB data, you must run all write operations in a transaction. This section shows how to manage a transaction in the following ways:

To start a Hibernate Transaction, call the beginTransaction() method on a Session instance. After you run operations and use the persist() method to register your changes with the session, commit the transaction by calling the commit() method.

The following example uses a transaction to create a new Movie entity and insert it as a document into the sample_mflix.movies collection. The highlighted lines begin and commit the transaction.

var sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
var newMovie = new Movie();
newMovie.setTitle("Lady Bird");
session.persist(newMovie);
tx.commit();
session.close();
sf.close();

To create a JPA EntityTransaction, call the getTransaction() method on your EntityManager. This method retrieves a EntityTransaction, which wraps the underlying Hibernate Transaction. Then, call the begin() method to start the transaction. After you run operations and use the persist() method to register your changes with the entity manager, commit the transaction by calling the commit() method.

The following example uses an EntityTransaction to delete a document from the sample_mflix.movies collection. The highlighted lines begin and commit the transaction.

// Replace <persistence unit> with the name of your persistence unit in the persistence.xml file
EntityManagerFactory emf = Persistence.createEntityManagerFactory("<persistence unit>");
EntityManager entityManager = emf.createEntityManager();
entityManager.getTransaction().begin();
// Your ObjectId value might differ
Movie movieToDelete = entityManager.find(Movie.class, new ObjectId("573a1399f29313caabcedc5d"));
entityManager.remove(movieToDelete);
entityManager.getTransaction().commit();
entityManager.close();
emf.close();

To discard all data changes from a transaction, call the rollback() method on a Hibernate Transaction or a JPA EntityTransaction. After calling this method, the Hibernate ORM reverts the uncommitted changes and clears the persistence context.

The following example rolls back the transaction if the code throws an error. Select the Hibernate Transaction or JPA EntityTransaction tab to see the corresponding code:

Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Movie movie = new Movie();
movie.setTitle("Control Alt Delete");
session.persist(movie);
tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
} finally {
session.close();
}
EntityManager entityManager = emf.createEntityManager();
EntityTransaction tx = entityManager.getTransaction();
try {
tx.begin();
Movie movie = new Movie();
movie.setTitle("Control Alt Delete");
entityManager.persist(movie);
tx.commit();
} catch (Exception e) {
if (tx != null && tx.isActive()) {
tx.rollback();
}
e.printStackTrace();
} finally {
entityManager.close();
}

To learn more about sessions and entity managers, see Persistence Context in the Hibernate ORM documentation.

To learn more about transactions, see Transactions in the Hibernate ORM documentation.

Back

Perform Native Queries

On this page