AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

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

このガイドでは、Hibernate ORM 用の MongoDB 拡張機能を使用してトランザクションを実行する方法を学ぶことができます。トランザクションを使用すると、トランザクション全体がコミットされた場合にのみデータを変更する一連の操作を実行できます。

MongoDBでは、トランザクションは論理セッション内で実行されます。セッションは 、順番に実行されるよう関連付けられた読み取り操作または書き込み操作のグループです。セッションにより、一連の操作に対する 因果整合性 が有効になり、ACID準拠のトランザクション内で操作を実行できるようになります。これは、アトミック性、整合性、分離、 耐久性 の期待を満たすトランザクションです。

Hibernetes ORM 拡張機能は、セッションとトランザクションを管理するための次の API をサポートしています。

  • Session を非表示: org.hibernate.Transaction APIを使用してデータベース操作をグループ化できます。詳細については、書き込み ORM ユーザーガイドの 非表示トランザクションAPI を参照してください。

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

このガイドの例では、AtlasサンプルデータセットのMovie sample_mflix.moviesコレクションを表す エンティティを使用します。Movie エンティティには、次の定義があります。

import com.mongodb.hibernate.annotations.ObjectIdGenerator;
import org.bson.types.ObjectId;
import java.time.Instant;
import java.util.List;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
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 List<String> cast;
private List<String> directors;
private Instant released;
@Embedded
private Awards awards;
@OneToMany(mappedBy = "movie", fetch = FetchType.LAZY)
private List<Comment> comments;
public Movie(String title, String plot, int year, List<String> cast, List<String> directors, Instant released, Awards awards) {
this.title = title;
this.plot = plot;
this.year = year;
this.cast = cast;
this.directors = directors;
this.released = released;
this.awards = awards;
}
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 List<String> getCast() {
return cast;
}
public void setCast(List<String> cast) {
this.cast = cast;
}
public List<String> getDirectors() {
return directors;
}
public void setDirectors(List<String> directors) {
this.directors = directors;
}
public Awards getAwards() {
return awards;
}
public void setAwards(Awards awards) {
this.awards = awards;
}
public Instant getReleased() {
return released;
}
public void setReleased(Instant released) {
this.released = released;
}
public List<Comment> getComments() {
return comments;
}
public void setComments(List<Comment> comments) {
this.comments = comments;
}
}

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

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

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

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

Tip

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

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

  1. getSessionFactory() メソッドを使用して、HibernateUtil ユーティリティクラスから SessionFactory を検索します。SessionFactory はMongoDB接続構成を保存し、新しいデータベースセッションを開くことができます。

  2. SessionFactoryインスタンスで openSession() メソッドを呼び出して Session を作成します。

  3. データベース操作を実行中したら、両方のインスタンスで 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();

次のコードに示すように、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ファイルを作成する必要があります。詳細を学ぶには、Hibernate ORM ドキュメントのJPA 標準 API を使用するチュートリアルを参照してください。

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

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

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

  3. データベース操作を実行中したら、両方のインスタンスで 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();

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() メソッドを呼び出してトランザクションをコミットします。

次の例では、トランザクションを使用して、sample_mflix.moviesコレクションに対して次の操作を実行しています。

  • 新しいMovieエンティティを作成し、それをドキュメントとしてコレクションに挿入します

  • title の値が "Black Swan" であるドキュメントの castフィールドを更新します

強調表示された行はトランザクションを開始し、コミットします。

var sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
var newMovie = new Movie();
newMovie.setTitle("Lady Bird");
newMovie.setYear(2017);
session.persist(newMovie);
var movie = session.createQuery("from Movie where title = :t", Movie.class)
.setParameter("t", "Black Swan")
.getSingleResult();
var currentCast = new ArrayList<>(movie.getCast());
currentCast.add("Winona Ryder");
movie.setCast(currentCast);
tx.commit();
session.close();
sf.close();

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

次の例では、EntityTransaction を使用して sample_mflix.moviesコレクションからドキュメントを削除し、タイトル値が "The Favourite" である新しいドキュメントを挿入します。強調表示された行はトランザクションを開始し、コミットします。

// 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);
var addMovie = new Movie();
addMovie.setTitle("The Favourite");
addMovie.setYear(2018);
entityManager.persist(addMovie);
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();
}

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

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