Overview
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 theorg.hibernate.TransactionAPI to group your database operations. To learn more, see Hibernate Transaction API in the Hibernate ORM user guide.Java
EntityManager永続性: Hibernetes ORM に を内部的に管理するように指示し、Sessionjakarta.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; public class Movie { 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 を使用して、 から を作成します
SessionSessionFactoryJPA EntityManager を使用する: Javaリスト永続化API を使用して から を作成します
EntityManagerEntityManagerFactory
一時停止セッションの使用
Tip
非表示 Session を起動するには、次の手順を実行します。
getSessionFactory()メソッドを使用して、HibernateUtilユーティリティクラスからSessionFactoryを取得します。SessionFactoryはMongoDB接続構成を保存し、新しいデータベースセッションを開くことができます。SessionFactoryインスタンスでopenSession()メソッドを呼び出してSessionを作成します。データベース操作を実行中たら、両方のインスタンスで
close()メソッドを使用してSessionFactoryとSessionを閉じます。
次の例では、データベースクエリを セッションで実行し、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();
JPA EntityManager の使用
Tip
EntityManagerを使用する前に、永続性ユニットを宣言するpersistence.xml ファイルを作成する必要があります。詳細については、 Hibernetes ORM ドキュメントの 「JPA 標準 API を使用するチュートリアル」 を参照してください。
Java 永続化API (JPA)EntityManager を起動するには、次の手順を実行します。
createEntityManagerFactory()メソッドを呼び出して、persistence.xmlファイルからEntityManagerFactoryを作成します。これにより、内部的にSessionFactoryが作成されます。EntityManagerFactoryインスタンスでcreateEntityManager()メソッドを呼び出してEntityManagerを作成します。これにより、内部的にSessionが作成されます。データベース操作を実行中たら、両方のインスタンスで
close()メソッドを呼び出して、EntityManagerFactoryとEntityManagerを閉じます。
次の例では、エンティティ マネージャーでデータベースクエリを実行し、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.TransactionAPI を使用して、 からトランザクションを開始しますSessionJPA EntityTransaction を使用する:
jakarta.persistence.EntityTransactionAPI を使用して、 からトランザクションを開始します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 の使用
JPA EntityTransaction を作成するには、EntityManager で getTransaction() メソッドを呼び出します。このメソッドでは、基礎となる 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 EntityTransaction で rollback() メソッドを呼び出します。このメソッドを呼び出した後、非表示 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 ドキュメントの「 トランザクション 」を参照してください。