検索

第12章 Jakarta Persistence

download PDF

12.1. Jakarta Persistence について

Jakarta Persistence は、Java オブジェクトまたはクラスとリレーショナルデータベース間でデータのアクセス、永続化、および管理を行うための Java 仕様です。この Jakarta Persistence 仕様では、透過オブジェクトまたはリレーショナルマッピングのパラダイムが考慮されます。オブジェクトまたはリレーショナル永続化メカニズムに必要な基本的な API とメタデータが標準化されます。

注記

Jakarta Persistence 自体は製品ではなく仕様にすぎません。それ自体では永続化やその他の処理を実行できません。Jakarta Persistence はインターフェースセットにすぎず、実装を必要とします。

12.2. 単純な JPA アプリケーションの作成

Red Hat CodeReady Studio で単純な JPA アプリケーションを作成する場合は、以下の手順を実行します。

  1. Red Hat CodeReady Studio で JPA プロジェクトを作成します。

    1. Red Hat CodeReady Studio で、File New Project の順にクリックします。リストで JPA を見つけ、展開し、JPA Project を選択します。以下のダイアログが表示されます。

      図12.1 新規 JPA プロジェクトダイアログ

      This is the new JPA Project dialog.
    2. プロジェクト名を入力します。
    3. Target runtime を選択します。ターゲットランタイムがない場合は、『Getting Started with Red Hat Developer Studio Tools 』の「Downloading, Installing, and Setting Up JBoss EAP from within the IDE」の手順に従って、新しいサーバーとランタイムを定義します。
    4. JPA version (JPA バージョン)2.1 が選択されていることを確認します。
    5. Configuration (設定)Basic JPA Configuration (基本的な JPA 設定) を選択します。
    6. Finish をクリックします。
    7. 要求されたら、このタイプのプロジェクトを JPA パースペクティブウインドウに関連付けるかどうかを選択します。
  2. 新しい永続性設定ファイルを作成および設定します。

    1. Red Hat CodeReady Studio で EJB 3.x プロジェクトを開きます。
    2. Project Explorer (プロジェクトエクスプローラー) パネルでプロジェクトルートディレクトリーを右クリックします。
    3. New(新規 )→ Other(その他)…​
    4. XML フォルダーから XML File (XML ファイル) を選択し、Next (次へ) をクリックします。
    5. 親ディレクトリーとして ejbModule/META-INF/ フォルダーを選択します。
    6. ファイルの名前を persistence.xml と指定し、Next (次へ) をクリックします。
    7. Create XML file from an XML schema file (XML スキーマファイルから XML ファイルを作成) を選択し、Next (次へ) をクリックします。
    8. Select XML Catalog entry (XML カタログエントリーを選択) リストから http://java.sun.com/xml/ns/persistence/persistence_2.0.xsd を選択し、Next (次へ) をクリックします。

      図12.2 永続 XML スキーマ

      Persistence XML Schema
    9. Finish (完了) をクリックしてファイルを作成します。persistence.xmlMETA-INF/ フォルダーに作成され、設定可能な状態になります。

      例: 永続設定ファイル

      <persistence xmlns="http://java.sun.com/xml/ns/persistence"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_2.xsd"
         version="2.2">
         <persistence-unit name="example" transaction-type="JTA">
            <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
            <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
            <mapping-file>ormap.xml</mapping-file>
            <jar-file>TestApp.jar</jar-file>
            <class>org.test.Test</class>
            <shared-cache-mode>NONE</shared-cache-mode>
            <validation-mode>CALLBACK</validation-mode>
            <properties>
               <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
               <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
            </properties>
         </persistence-unit>
      </persistence>

12.3. Jakarta Persistence エンティティー

アプリケーションからデータベースへの接続を確立したら、データベースのデータを Java オブジェクトにマッピングできます。データベーステーブルに対してマップするために使用される Java オブジェクトはエンティティーオブジェクトと呼ばれます。

エンティティーは別のエンティティーと関係を持ち、そのような関係はオブジェクトリレーショナルメタデータを介して表現されます。オブジェクトリレーショナルメタデータは、アノテーションを使用してエンティティークラスファイルに直接指定するか、アプリケーションに含まれる persistence.xml という XML 記述ファイルで指定できます。

Java オブジェクトからデータベースへのマッピングの概要は次のとおりです。

  • Java クラスはデータベーステーブルにマップします。
  • Java インスタンスはデータベース行にマップします。
  • Java フィールドはデータベース列にマップします。

12.4. 永続コンテキスト

Jakarta Persistence 永続コンテキストには、永続プロバイダーによって管理されるエンティティーが含まれます。永続コンテキストは、データソースと対話するための 1 次レベルトランザクションキャッシュのように動作します。これは、エンティティーインスタンスおよびそれらのライフサイクルを管理します。ロードされたエンティティーは、アプリケーションに返される前に永続コンテキストに置かれます。エンティティーの変更も永続コンテキストに置かれ、トランザクションのコミットが実行されるとデータベースに保存されます。

コンテナー管理永続性 (CMP) コンテキストは、トランザクションにスコープ付けするか (トランザクションスコープの永続コンテキストと呼ばれます)、単一トランザクションを超えて拡張するライフタイムスコープを持つことができます (拡張永続コンテキストと呼ばれます)。enum データタイプを持つ PersistenceContextType プロパティーは、コンテナー管理エンティティーマネージャーの永続コンテキストライフタイムスコープを定義するために使用されます。永続コンテキストのライフタイムスコープは、EntityManager インスタンスの作成時に定義されます。

12.4.1. トランザクションスコープの永続コンテキスト

トランザクションスコープの永続コンテキストは、アクティブな Jakarta Transactions トランザクションと動作します。トランザクションがコミットすると、永続コンテキストはデータソースにフラッシュされます。エンティティーオブジェクトはデタッチされますが、アプリケーションコードによって参照されることがあります。データソースに保存されることが想定されるエンティティーの変更はすべてトランザクション中に行われる必要があります。トランザクション外部で読み取られるエンティティーは、EntityManager 呼び出しが完了するとデタッチされます。

12.4.2. 拡張永続コンテキスト

拡張永続コンテキストは複数のトランザクションにまたがり、アクティブが Jakarta Transactions トランザクションがなくてもデータの変更をキューに置けるようにします。コンテナー管理の拡張永続コンテキストは、ステートフルセッション bean のみへインジェクトできます。

12.5. Jakarta Persistence EntityManager

Jakarta Persistence エンティティーマネージャーは、永続コンテキストへの接続を表します。エンティティーマネージャーを使用して永続コンテキストによって定義されるデータベースの読み書きが可能です。

永続コンテキストは、javax.persistence パッケージの Java アノテーション @PersistenceContext を介して提供されます。エンティティーマネージャーは、Java クラス javax.persistence.EntityManager を介して提供されます。管理対象 bean では、以下のように EntityManager インスタンスをインジェクトできます。

例: エンティティーマネージャーのインジェクション

@Stateless
public class UserBean {
    @PersistenceContext
    EntityManager entitymanager;
    ...
}

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

アプリケーション管理のエンティティーマネージャーは基盤の永続プロバイダーである org.hibernate.jpa.HibernatePersistenceProvider への直接アクセスを提供します。アプリケーション管理のエンティティーマネジャーの範囲は、アプリケーションによって作成された時からアプリケーションによってクローズされるまでです。@PersistenceUnit アノテーションを使用して、永続ユニットを javax.persistence.EntityManagerFactory インターフェースにインジェクトできます。これにより、アプリケーション管理のエンティティーマネジャーが返されます。

アプリケーション管理のエンティティーマネージャーは、特定の永続ユニットにて EntityManager インスタンスすべてで Jakarta Transactions トランザクションを使用して伝搬されていない永続コンテキストへアプリケーションがアクセスする必要があるときに使用できます。この場合、各 EntityManager インスタンスは新たに分離された永続コンテキストを作成します。EntityManager インスタンスと関連する PersistenceContext は、アプリケーションによって明示的に作成および破棄されます。EntityManager インスタンスはスレッドセーフではないため、EntityManager インスタンスを直接インジェクトできないときにアプリケーション管理のエンティティーマネージャーを使用することもできます。EntityManagerFactory はスレッドセーフです。

例: アプリケーション管理のエンティティーマネージャー

@PersistenceUnit
EntityManagerFactory emf;
EntityManager em;
@Resource
UserTransaction utx;
...
em = emf.createEntityManager();
try {
    utx.begin();
    em.persist(SomeEntity);
    em.merge(AnotherEntity);
    em.remove(ThirdEntity);
    utx.commit();
}
catch (Exception e) {
    utx.rollback();
}

12.5.2. コンテナー管理の EntityManager

コンテナー管理のエンティティーマネージャーは、アプリケーションの基盤となる永続プロバイダーを管理します。トランザクションスコープの永続コンテキストまたは拡張永続コンテキストを使用できます。コンテナー管理のエンティティーマネージャーは、必要に応じて基盤となる永続プロバイダーのインスタンスを作成します。基盤の永続プロバイダー org.hibernate.jpa.HibernatePersistenceProvider インスタンスが新たに作成されるたびに、新しい永続コンテキストも作成されます。

12.6. EntityManager の利用

/META-INF ディレクトリーに persistence.xml ファイルがある場合、エンティティーマネージャーはロードされ、データベースにアクティブに接続されます。EntityManager プロパティーを使用して、エンティティーマネージャーを JNDI にバインドし、エンティティーを追加、更新、削除、およびクエリーできます。

重要

Hibernate でセキュリティーマネージャーの使用を計画している場合は、EntityManagerFactory が JBoss EAP サーバーによってブートストラップされている場合のみ Hibernate がサポートすることに注意してください。EntityManagerFactory または SessionFactory がアプリケーションによってブートストラップされている場合はサポートされません。セキュリティーマネージャーに関する詳細は、『 How to Configure Server Security』の「 Java Security Manager 」を参照してください。

12.6.1. EntityManager の JNDI へのバインディング

デフォルトでは、JBoss EAP は EntityManagerFactory を JNDI にバインドしません。jboss.entity.manager.factory.jndi.name プロパティーを設定すると、アプリケーションの persistence.xml ファイルでこれを明示的に設定できます。このプロパティーの値は、EntityManagerFactory をバインドする JNDI の名前にする必要があります。

また、jboss.entity.manager.jndi.name プロパティーを使用すると、コンテナー管理でトランザクションスコープのエンティティーマネージャーを JNDI にバインドすることもできます。

例: EntityManager および EntityManagerFactory の JNDI へのバインド

<property name="jboss.entity.manager.jndi.name" value="java:/MyEntityManager"/>
<property name="jboss.entity.manager.factory.jndi.name" value="java:/MyEntityManagerFactory"/>

例: EntityManager を使用したエンティティーの格納

public User createUser(User user) {
    entityManager.persist(user);
    return user;
}

例: EntityManager を使用したエンティティーの更新

public void updateUser(User user) {
    entityManager.merge(user);
}

例: EntityManager を使用したエンティティーの削除

public void deleteUser(String user) {
    User user = findUser(username);
    if (user != null)
        entityManager.remove(user);
}

例: EntityManager を使用したエンティティーのクエリー

public User findUser(String username) {
    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    CriteriaQuery<User> criteria = builder.createQuery(User.class);
    Root<User> root = criteria.from(User.class);
    TypedQuery<User> query = entityManager
        .createQuery(criteria.select(root).where(
            builder.equal(root.<String> get("username"), username)));
    try {
        return query.getSingleResult();
    }
    catch (NoResultException e) {
        return null;
    }
}

12.7. 永続ユニットのデプロイ

永続ユニットは、以下が含まれる論理グループです。

  • エンティティーマネージャーファクトリーおよびそのエンティティーマネージャーの設定情報。
  • エンティティーマネージャーによって管理されるクラス。
  • データベースへのクラスのマッピングを指定するメタデータのマッピング。

persistence.xml ファイルには、データソース名を含む永続ユニット設定が含まれています。/META-INF/ ディレクトリーに persistence.xml ファイルが含まれる JAR ファイルまたはディレクトリーは、永続ユニットのルートと呼ばれます。

Jakarta EE 環境では、永続ユニットのルートは以下の 1 つである必要があります。

  • EJB-JAR ファイル
  • WAR ファイルの /WEB-INF/classes/ ディレクトリー
  • WAR ファイルの /WEB-INF/lib/ ディレクトリーにある JAR ファイル
  • EAR ライブラリーディレクトリーの JAR ファイル
  • アプリケーションクライアントの JAR ファイル

例: 永続設定ファイル

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_2.xsd"
   version="2.2">
   <persistence-unit name="example" transaction-type="JTA">
      <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
      <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
      <mapping-file>ormap.xml</mapping-file>
      <jar-file>TestApp.jar</jar-file>
      <class>org.test.Test</class>
      <shared-cache-mode>NONE</shared-cache-mode>
      <validation-mode>CALLBACK</validation-mode>
      <properties>
         <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
         <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
      </properties>
   </persistence-unit>
</persistence>

12.8. 2 次キャッシュ

12.8.1. 2 次キャッシュ

2 次キャッシュとは、アプリケーションセッション外部で永続化された情報を保持するローカルデータストアのことです。このキャッシュは永続プロバイダーにより管理され、アプリケーションとデータを分離することでランタイムを改善します。

JBoss EAP では、以下の目的のためにキャッシュがサポートされます。

  • Web セッションのクラスタリング
  • ステートフルセッション Bean のクラスタリング
  • SSO クラスタリング
  • Hibernate 2 次キャッシュ
  • Jakarta Persistence の 2 次キャッシュ
警告

各キャッシュコンテナーは repl および dist キャッシュを定義します。これらのキャッシュは、ユーザーアプリケーションで直接使用しないでください。

12.8.1.1. デフォルトの 2 次キャッシュプロバイダー

Infinispan は、JBoss EAP のデフォルトの 2 次キャッシュプロバイダーです。Infinispan は、オプションのスキーマを持つ分散型のインメモリーキーと値のデータストアで、Apache License 2.0 で利用できます。

12.8.1.1.1. 永続ユニットでの 2 次レベルキャッシュの設定

永続ユニットの shared-cache-mode 要素を使用して 2 次レベルキャッシュを設定できます。

  1. 単純な Jakarta Persistence アプリケーションの作成」を参照して、Red Hat CodeReady Studio で persistence.xml ファイルを作成します。
  2. 以下の内容を persistence.xml ファイルに追加します。

    <persistence-unit name="...">
      (...) <!-- other configuration -->
      <shared-cache-mode>SHARED_CACHE_MODE</shared-cache-mode>
      <properties>
        <property name="hibernate.cache.use_second_level_cache" value="true" />
        <property name="hibernate.cache.use_query_cache" value="true" />
      </properties>
    </persistence-unit>

    SHARED_CACHE_MODE 要素には以下の値を指定できます。

    • ALL: すべてのエンティティーがキャッシュ可能と見なされます。
    • NONE: キャッシュ可能と見なされるエンティティーはありません。
    • ENABLE_SELECTIVE: キャッシュ可能とマークされたエンティティーのみがキャッシュ可能と見なされます。
    • DISABLE_SELECTIVE: 明示的にキャッシュ不可能であるとマークされたエンティティーを除くすべてのエンティティーがキャッシュ可能と見なされます。
    • UNSPECIFIED: 動作は定義されません。プロバイダー固有のデフォルトは提供されます。
Red Hat logoGithubRedditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

© 2024 Red Hat, Inc.