MongoDB.local SF, Jan 15: See the speaker lineup & ship your AI vision faster. Use WEB50 to save 50%
Find out more >
Docs Menu
Docs Home
/ /

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

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

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

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

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

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

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

import com.mongodb.hibernate.annotations.ObjectIdGenerator;
import org.bson.types.ObjectId;
import java.util.List;
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 List<String> cast;
public Movie(String title, String plot, int year, List<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 List<String> getCast() {
return cast;
}
public void setCast(List<String> cast) {
this.cast = cast;
}
}

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

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

Tip

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

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

Jakarta 永続化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データを変更するには、トランザクション内ですべての書き込み操作を実行する必要があります。このセクションでは、次の方法でトランザクションをマネージドする方法を説明します。

非表示 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 を作成するには、EntityManagergetTransaction() メソッドを呼び出します。このメソッドでは、基礎の 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 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();
}

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

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

戻る

ネイティブ クエリの実行

項目一覧