Docs Menu
Docs Home
/ /

トランザクションとセッション

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準拠のトランザクション内で操作を実行できるようになります。これは、アトミック性、整合性、分離、 耐久性 の期待を満たすトランザクションです。

Hibernetes 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.

  • JavaEntityManager 永続性: Hibernetes ORM に を内部的に管理するように指示し、Session jakarta.persistence.EntityTransactionAPI を使用してデータベース操作をグループ化できるようにします。詳細については、Java EA ドキュメントの javarta.persistencyパッケージを参照してください。

このガイドの例では、AtlasサンプルデータセットのMovie 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;
}
}

Hibernetes ORM 用のMongoDB拡張機能 を使用してこのMongoDBサンプルコレクションを操作するJavaアプリケーションを作成する方法については、「 を使い始める 」チュートリアルを参照してください。

MongoDBデータを操作するには、すべてのデータベース操作をセッション内で実行する必要があります。このセクションでは、データベースセッションを次の方法で管理する方法を説明します。

  • 非表示セッションを使用する: 非表示のネイティブAPI を使用して、 から を作成しますSessionSessionFactory

  • JPA EntityManager を使用する: Javaリスト永続化API を使用して から を作成しますEntityManagerEntityManagerFactory

Tip

Sessionを使用する前に、HibernateUtil.java を構成するSessionFactory ファイルを作成する必要があります。詳細については、「 使い始める 」チュートリアルの「 アプリケーションを構成する 」の手順を参照してください。

非表示 Session を起動するには、次の手順を実行します。

  1. getSessionFactory() メソッドを使用して、HibernateUtil ユーティリティクラスから SessionFactory を取得します。 SessionFactory は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();

Tip

EntityManagerを使用する前に、永続性ユニットを宣言するpersistence.xml ファイルを作成する必要があります。詳細については、 Hibernetes ORM ドキュメントの 「JPA 標準 API を使用するチュートリアル」 を参照してください。

Java 永続化API (JPA)EntityManager を起動するには、次の手順を実行します。

  1. createEntityManagerFactory() メソッドを呼び出して、persistence.xmlファイルから EntityManagerFactory を作成します。これにより、内部的に SessionFactory が作成されます。

  2. EntityManagerFactoryインスタンスで createEntityManager() メソッドを呼び出して EntityManager を作成します。これにより、内部的に Session が作成されます。

  3. データベース操作を実行中たら、両方のインスタンスで close() メソッドを呼び出して、EntityManagerFactoryEntityManager を閉じます。

次の例では、エンティティ マネージャーでデータベースクエリを実行し、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

Java の永続性3.1 v 以降では、EntityManager 非表示のセッション のセクションに示されているように、Java のtry-with-resources ステートメントを使用して を自動的に閉じることができます。

MongoDBデータを変更するには、トランザクション内ですべての書き込み操作を実行する必要があります。このセクションでは、次の方法でトランザクションを管理する方法を説明します。

  • 非表示トランザクションを使用する: 非表示のネイティブorg.hibernate.Transaction API を使用して、 からトランザクションを開始しますSession

  • JPA EntityTransaction を使用する:jakarta.persistence.EntityTransaction API を使用して、 からトランザクションを開始しますEntityManager

非表示 Transaction を起動するには、Sessionインスタンスで beginTransaction() メソッドを呼び出します。操作を実行し、persist() メソッドを使用して変更をセッションに登録した後、commit() メソッドを呼び出してトランザクションをコミットします。

次の例では、トランザクションを使用して新しい Movie エンティティを作成し、それをドキュメントとして sample_mflix.moviesコレクションに挿入します。強調表示された行はトランザクションを開始し、コミットします。

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 を作成するには、EntityManagergetTransaction() メソッドを呼び出します。このメソッドでは、基礎となる Hibernetes Transaction をラップする EntityTransaction が検索されます。次に、begin() メソッドを呼び出してトランザクションを開始します。操作を実行し、persist() メソッドを使用してエンティティ マネージャーに変更を登録した後、commit() メソッドを呼び出してトランザクションをコミットします。

次の例では、EntityTransaction を使用して sample_mflix.moviesコレクションからドキュメントを削除します。強調表示された行はトランザクションを開始し、コミットします。

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

トランザクションからすべてのデータ変更を破棄するには、 Hibernetes Transaction または JPA EntityTransactionrollback() メソッドを呼び出します。このメソッドを呼び出した後、非表示 ORM はコミットされていない変更を元に戻し、永続性コンテキストをクリアします。

次の例では、コードがエラーをスローした場合にトランザクションをロールバックします。対応するコードを表示するには、Hibernate Transaction タブまたは JPA 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();
}

セッションとエンティティ マネージャーの詳細については、 Hibernetes ORM ドキュメントの 永続性コンテキスト を参照してください。

トランザクションの詳細については、 Hibernetes ORM ドキュメントの「 トランザクション 」を参照してください。

戻る

ネイティブ クエリの実行

項目一覧