Hibernate EntityManagerのガイド

1.はじめに

  • EntityManager は、Java Persistence APIの一部です。主に、JPA 2.0仕様で定義されているプログラミングインタフェースとライフサイクルルールを実装しています。

さらに、 EntityManager のAPIを使用して、永続コンテキストにアクセスできます。

このチュートリアルでは、 EntityManager の構成、型、そしてさまざまなAPIについて見ていきます。

2. Mavenの依存関係

まず、Hibernateの依存関係を含める必要があります。

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.4.0.Final</version>
</dependency>

使用しているデータベースに応じて、ドライバの依存関係も含める必要があります。

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.13</version>
</dependency>

hibernate-core およびhttps://search.maven.org/search?q=a: mysql-connector-java%20AND%20g:mysql[mysql-connector-java]の依存関係はMaven Centralで利用可能です。

3.設定

それでは、データベース内のMOVIEテーブルに対応する Movie エンティティを使用して、 EntityManager を説明しましょう。

この記事では、 EntityManager APIを使用してデータベース内の Movie オブジェクトを処理します。

3.1. エンティティの定義

@ Entity アノテーションを使ってMOVIEテーブルに対応するエンティティを作成することから始めましょう:

@Entity
@Table(name = "MOVIE")
public class Movie {

    @Id
    private Long id;

    private String movieName;

    private Integer releaseYear;

    private String language;

   //standard constructor, getters, setters
}

3.2. persistence.xml ファイル

EntityManagerFactory が作成されると、** 永続化実装はクラスパス内で META-INF/persistence.xml ファイルを検索します。

  • このファイルには、 EntityManager の設定が含まれています。

<persistence-unit name="com.baeldung.movie__catalog">
    <description>Hibernate EntityManager Demo</description>
    <class>com.baeldung.hibernate.pojo.Movie</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
        <property name="hibernate.hbm2ddl.auto" value="update"/>
        <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
        <property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/moviecatalog"/>
        <property name="javax.persistence.jdbc.user" value="root"/>
        <property name="javax.persistence.jdbc.password" value="root"/>
    </properties>
</persistence-unit>

説明のために、 EntityManager によって管理される基礎となるデータストアを指定するpersistence-unitを定義します。

さらに、基礎となるデータストアの方言とその他のJDBCプロパティを定義します。 Hibernateはデータベースに依存しません。 ** これらのプロパティに基づいて、Hibernateは基礎となるデータベースと接続します。

4.コンテナ管理とアプリケーション管理 EntityManager

基本的に、__EntityManagerには、コンテナ管理とアプリケーション管理の2種類があります。

それぞれのタイプを詳しく見てみましょう。

4.1. コンテナ管理 EntityManager

ここでは、コンテナが私たちのエンタープライズコンポーネントに EntityManager を注入します。

つまり、コンテナは EntityManagerFactory から EntityManager を作成します。

@PersistenceContext
EntityManager entityManager;

これは、コンテナがトランザクションの開始、コミット、またはロールバックを担当することも意味します。

4.2. アプリケーション管理 EntityManager

逆に、 EntityManager のライフサイクルは、ここでアプリケーションによって管理されます。

実際には、 EntityManagerを手動で作成します。さらに、作成した EntityManager__のライフサイクルも管理します。

まず、__EntityManagerFactoryを作成しましょう。

EntityManagerFactory emf = Persistence.createEntityManagerFactory("com.baeldung.movie__catalog");

EntityManager を作成するには、 EntityManagerFactory createEntityManager() を明示的に呼び出す必要があります。

public static EntityManager getEntityManager() {
    return emf.createEntityManager();
}

5. Hibernateエンティティの操作

EntityManager APIは、一連のメソッドを提供します。これらの方法を利用することで、データベースと対話することができます。

5.1. 永続エンティティ

EntityManagerに関連付けられたオブジェクトを持つために、 persist() メソッドを利用することができます。

public void saveMovie() {
    EntityManager em = getEntityManager();

    em.getTransaction().begin();

    Movie movie = new Movie();
    movie.setId(1L);
    movie.setMovieName("The Godfather");
    movie.setReleaseYear(1972);
    movie.setLanguage("English");

    em.persist(movie);
    em.getTransaction().commit();
}
  • オブジェクトがデータベースに保存されると、それは persistent 状態になります。

5.2. エンティティの読み込み

  • データベースからオブジェクトを取得するために、 find() メソッドを使うことができます。

ここでは、メソッドは主キーで検索します。実際、このメソッドはエンティティクラスタイプと主キーを期待します。

public Movie getMovie(Long movieId) {
    EntityManager em = getEntityManager();
    Movie movie = em.find(Movie.class, new Long(movieId));
    em.detach(movie);
    return movie;
}
  • ただし、エンティティへの参照が必要な場合は、代わりに getReference() ** メソッドを使用できます。実際には、エンティティにプロキシを返します。

Movie movieRef = em.getReference(Movie.class, new Long(movieId));

5.3. エンティティの切り離し

永続化コンテキストからエンティティを切り離す必要がある場合は、__detach()メソッドを使用できます。デタッチするオブジェクトをパラメータとしてメソッドに渡します。

em.detach(movie);

エンティティが永続コンテキストからデタッチされると、それはデタッチ状態になります。

5.4. エンティティの結合

実際には、多くのアプリケーションは複数のトランザクションにわたってエンティティの変更を必要とします。たとえば、UIへのレンダリングのために1つのトランザクションでエンティティを取得したい場合があります。その後、別のトランザクションがUIで行われた変更を取り込みます。

そのような状況では、 merge() メソッドを利用できます。 ** マージメソッドは、もしあれば、管理エンティティ内で、デタッチされたエンティティに対して行われた変更を取り込むのに役立ちます。

public void mergeMovie() {
    EntityManager em = getEntityManager();
    Movie movie = getMovie(1L);
    em.detach(movie);
    movie.setLanguage("Italian");
    em.getTransaction().begin();
    em.merge(movie);
    em.getTransaction().commit();
}

5.5. エンティティの問い合わせ

さらに、エンティティを問い合わせるのにJPQLを利用することができます。それらを実行するために getResultList() を呼び出します。

もちろん、クエリが単一のオブジェクトを返す場合は、__getSingleResult()を使用できます。

public List<?> queryForMovies() {
    EntityManager em = getEntityManager();
    List<?> movies = em.createQuery("SELECT movie from Movie movie where movie.language = ?1")
      .setParameter(1, "English")
      .getResultList();
    return movies;
}

5.6. エンティティの削除

さらに、** remove() メソッドを使ってデータベースからエンティティを削除することもできます。オブジェクトは切り離されずに削除されることに注意することが重要です。

ここでは、エンティティの状態が永続から新規に変わります。

public void removeMovie() {
    EntityManager em = HibernateOperations.getEntityManager();
    em.getTransaction().begin();
    Movie movie = em.find(Movie.class, new Long(1L));
    em.remove(movie);
    em.getTransaction().commit();
}

6.まとめ

この記事では、Hibernateの EntityManager について説明しました。

型と設定を見てきました。そして、__persistenceコンテキストを扱うためにAPIで利用できるさまざまなメソッドについて学びました。

いつものように、この記事で使われているコードはhttps://github.com/eugenp/tutorials/tree/master/persistence-modules/hibernate5[Githubで公開]です。