Docs 菜单
Docs 主页
/ /

事务和会话

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.

在MongoDB中,事务在逻辑会话中运行。会话是要按顺序运行的一组相关读取或写入操作。会话启用为一群组操作启用因果一致性,并允许您在符合ACID的ACID 事务中运行操作,该ACID 事务满足原子性、一致性、隔离性和持久性的预期。

Hibernate ORM 扩展支持以下用于管理会话和事务的 API:

  • 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 PersistenceEntityManager :指示 Hibernate ORMSession 在内部管理 ,并允许您使用jakarta.persistence.EntityTransaction API对数据库操作群组。要学习;了解更多信息,请参阅 Jakarta EE 文档中的 jakarta.persistence包。

本指南中的示例使用Movie 实体,它表示Atlas示例数据集中的sample_mflix.movies 集合。Movie 实体具有以下定义:

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;
}
}

要学习;了解如何创建Java应用程序以使用MongoDB Extension for Hibernate ORM 与此MongoDB示例集合交互,请参阅 入门教程。

要与MongoDB数据交互,您必须在会话中运行所有数据库操作。本节介绍如何通过以下方式管理数据库会话:

提示

在使用Session 之前,您必须创建一个配置HibernateUtil.javaSessionFactory 文件。要学习;了解更多信息,请参阅入门教程中的配置应用程序步骤。

要启动 Hibernate Session,请执行以下步骤:

  1. 使用 getSessionFactory() 方法从 HibernateUtil 实用程序类中检索 SessionFactorySessionFactory 存储您的MongoDB连接配置,并且可以打开新的数据库会话。

  2. 通过在 SessionFactory实例上调用 openSession() 方法来创建 Session

  3. 运行数据库操作后,对这两个实例使用 close() 方法关闭 SessionFactorySession

以下示例在会话中运行数据库查询,并从 sample_mflix.movies集合中检索 title 值为 "Erin Brockovich" 的文档:

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

还可以使用 Java 的 try-with-resources声明来简化会话管理逻辑并自动关闭会话,如以下代码所示:

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();

提示

在使用EntityManager 之前,您必须创建一个声明持久性单元的persistence.xml 文件。要学习;了解更多信息,请参阅 Hibernate ORM 文档中的使用 JPA 标准 API 的教程。

要启动 Jakarta Persistence API (JPA) EntityManager,请执行以下步骤:

  1. 通过调用 createEntityManagerFactory() 方法从 persistence.xml文件创建 EntityManagerFactory,该方法会在内部创建 SessionFactory

  2. 通过对 EntityManagerFactory实例调用 createEntityManager() 方法来创建 EntityManager,这会在内部创建 Session

  3. 运行数据库操作后,在 EntityManagerFactoryEntityManager 实例上调用 close() 方法以关闭这两个实例。

以下示例在实体管理器中运行数据库查询,并从 sample_mflix.movies集合中检索 year 值为 1929 的文档:

// 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

在 Jakarta Persistence v3.1 或更高版本中,您可以使用 Java 的 try-with-resources声明自动关闭 EntityManager,如“Hibernate 会话”部分所示。

要修改MongoDB数据,必须在ACID 事务中运行所有写入。本节介绍如何通过以下方式管理ACID 事务:

要启动 Hibernate Transaction,请在 Session实例上调用 beginTransaction() 方法。运行操作并使用 persist() 方法在会话中注册更改后,通过调用 commit() 方法提交ACID 事务。

以下示例使用ACID 事务创建新的 Movie 实体,并将其作为文档插入到 sample_mflix.movies集合中。突出显示的行开始并提交ACID 事务。

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();

要创建 JPA EntityTransaction,请对 EntityManager 调用 getTransaction() 方法。此方法检索一个 EntityTransaction,其中包装了根本的Hibernate Transaction。然后,调用 begin() 方法启动ACID 事务。运行操作并使用 persist() 方法向实体管理器注册更改后,通过调用 commit() 方法提交ACID 事务。

以下示例使用 EntityTransactionsample_mflix.movies集合中删除文档。突出显示的行开始并提交ACID 事务。

// 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();

要放弃ACID 事务中的所有数据更改,请对 Hibernate Transaction 或 JPA EntityTransaction 调用 rollback() 方法。调用此方法后,Hibernate ORM 将恢复未提交的更改并清除持久化上下文。

以下示例将在代码抛出错误时回滚ACID 事务。选择 Hibernate TransactionJPA EntityTransaction标签页以查看相应的代码:

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();
}

要学习;了解有关会话和实体管理器的更多信息,请参阅 Hibernate ORM 文档中的持久化上下文。

要学习;了解有关事务的更多信息,请参阅 Hibernate ORM 文档中的事务。

后退

执行原生查询

在此页面上