ヘッダーをスキップ
Oracle® Fusion Middleware Oracle TopLinkのためのCoherence Grid統合ガイド
11g リリース1(11.1.1)
B61395-02
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次
索引へ移動
索引

前
 
次
 

2 グリッド基盤のJPA構成

この章の内容は次のとおりです。

2.1 グリッド基盤のJPAについて

グリッド基盤のJPAという表現は、JPAとデータ・グリッドの機能を使用してスケーラビリティとパフォーマンスが向上したアプリケーションを構築することを意味します。グリッド基盤のJPAアプローチでは、TopLink Gridによって、キャッシュのセットと、EclipseLink JPAでのCoherenceの使用方法を制御できる問合せ構成オプションが提供されます。

Coherenceを分散共有(L2)キャッシュとして構成することも、Coherenceをプライマリ・データ・ストアとして使用することもできます。また、データベースのかわりにCoherenceデータ・グリッド内で問合せを実行するようエンティティを構成することもできます。これにより、クラスタ・アプリケーションのデプロイメントで、通常のデータベース操作の限界を超えるスケーラビリティが得られます。

図2-1に、アプリケーション、TopLink、Coherenceおよびデータベース間の関係を示します。

図2-1 グリッド基盤のJPAアプローチ

グリッド基盤のJPAのアプローチです。
「図2-1 グリッド基盤のJPAアプローチ」の説明

2.2 グリッド基盤のJPAのAPI

グリッド基盤のJPA構成で使用されるAPIは、toplink-grid.jarファイルに含まれています。表2-1に、グリッド基盤のJPA構成で使用されるoracle.eclipselink.coherence.integratedパッケージの主要クラスの一部をリストします。

表2-1 グリッド基盤のJPAアプリケーションを構築するためのTopLink Gridクラス

クラス名 説明

oracle.eclipseLink.coherence.integrated.EclipseLinkJPACacheLoader

Coherence CacheLoaderインタフェースのJPA対応バージョンを提供します。

oracle.eclipseLink.coherence.integrated.EclipseLinkJPACacheStore

Coherence CacheStoreインタフェースのJPA対応バージョンを提供します。

oracle.eclipselink.coherence.integrated.config.CoherenceReadCustomizer

Coherence読取り構成を有効にします。

oracle.eclipselink.coherence.integrated.config.CoherenceReadWriteCustomizer

Coherence読取り/書込み構成を有効にします。

oracle.eclipselink.coherence.integrated.config.GridCacheCustomizer

キャッシュ・インスタンスを内部EclipseLink共有キャッシュのかわりにCoherenceにキャッシュできるようにします。内部TopLink L2キャッシュに対するすべてのコールは、Coherenceにリダイレクトされます。

oracle.eclipselink.coherence.integrated.querying.IgnoreDefaultRedirector

問合せがCoherenceキャッシュをバイパスし、データベースに直接送信されるようにします。


構成では、標準JPAランタイム構成ファイルpersistence.xmlおよびJPAマッピング・ファイルorm.xmlも使用されます。Coherenceキャッシュ構成ファイルcoherence-cache-config.xmlを使用してデフォルトのCoherence設定をオーバーライドし、キャッシュ・ストア・キャッシュ・スキームを定義する必要もあります。

2.3 グリッド・キャッシュ構成

グリッド・キャッシュ構成は、TopLink Gridの基本構成とみなすことができます。この構成では、CoherenceがTopLink共有(L2)キャッシュとして機能します。これにより、Coherenceのキャッシュにすべて事前ロードできずデータベースでホストされるデータに依存するJPAアプリケーションに対してCoherenceのデータ・グリッドを適用できます。データを事前ロードできない理由には、Coherenceのフィルタの機能を超える非常に複雑な問合せ、サード・パーティ製データベースの更新による古いキャッシュ、およびネイティブSQL問合せ、ストアド・プロシージャ、トリガーへの依存などがあります。

CoherenceをTopLink Gridキャッシュとして使用すると、ローカル共有キャッシュを調整しなくても、TopLinkを大規模なクラスタにスケール・アップできます。エンティティに対する更新は、トランザクションがコミットされると即時にすべてのCoherenceクラスタ・メンバーで使用可能になります。

一般に、グリッド・キャッシュ構成の読取りおよび書込み操作には次の特徴があります。

詳細な例については、「グリッド・キャッシュ構成の例」を参照してください。

Coherenceをエンティティの分散キャッシュとして使用するには、EclipseLinkで共有キャッシュを有効にする必要があります。共有キャッシュは、すべてのエンティティに対してデフォルトで有効になりますが、デフォルトはpersistence.xmlファイルでeclipselink.cache.shared.defaultプロパティを設定することで明示的にtrueまたはfalseに設定できます。特定のエンティティは、@Cache注釈を使用するか、eclipselink-orm.xmlファイルで対応するXML <cache>要素を指定することでオーバーライドできます。

http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_(ELUG)#How_to_Use_the_.40Cache_Annotation

2.3.1 グリッド・キャッシュ構成でのオブジェクトの読取り

グリッド・キャッシュ構成では、最初にCoherenceキャッシュに送られる主キー問合せを除くすべての読取り問合せがデータベースに送られます。キャッシュ・ミスがあった場合は、データベース問合せが実行されます。

データベースから問合せされたすべてのエンティティはCoherenceキャッシュに挿入されます。これにより、エンティティはすべてのクラスタ・メンバーに対して即時に使用可能になります。TopLinkはデフォルトで、データベース結果からの新しいエンティティの構成を回避するためにキャッシュを利用するため、この動作が非常に有効になります。

TopLinkは、問合せの結果返された行ごとに、結果の行の主キーを使用して、キャッシュから対応するエンティティを問い合せます。キャッシュにエンティティが含まれていれば、そのエンティティが使用され、新しいエンティティは構築されません。このアプローチではオブジェクトのビルドに関連するコストを排除することで問合せのコストを削減できるため、特にウォーム・キャッシュを使用する場合は、アプリケーションのパフォーマンスが大幅に向上する可能性があります。

図2-2に、グリッド・キャッシュ構成での読取り問合せのパスを示します。

  1. アプリケーションがfind問合せを発行します。

  2. 主キー問合せでは、TopLinkは最初にCoherenceキャッシュを問い合せます。

  3. オブジェクトがCoherenceキャッシュに存在しない場合、TopLinkはデータベースを問い合せます。

    主キー問合せを除くすべての読取り問合せでは、TopLinkは最初にデータベースを問い合せます。

  4. 読み取られたオブジェクトは、Coherenceキャッシュに挿入されます。

図2-2 グリッド・キャッシュ構成でのオブジェクトの読取り

オブジェクトの読取り。
「図2-2 グリッド・キャッシュ構成でのオブジェクトの読取り」の説明

2.3.2 グリッド・キャッシュ構成でのオブジェクトの書込み

グリッド・キャッシュ構成では、TopLinkがすべてのデータベース書込み操作(挿入、更新、削除)を実行します。その後、Coherenceキャッシュがデータベースへの変更を反映するように更新されます。TopLinkには、大量のデータを書き込む際のパフォーマンス機能が数多く用意されています(バッチ書込み、パラメータ・バインディング、ストアド・プロシージャ・サポート、データベース制約を満たすための文の順序付けなど)。

図2-3に、グリッド・キャッシュ構成でのオブジェクトの書込みと永続化のパスを示します。

  1. アプリケーションがcommit問合せを発行します。

  2. TopLinkがデータベースを更新します。

  3. トランザクションが正常に完了すると、TopLinkはCoherenceキャッシュを更新します。

図2-3 グリッド・キャッシュ構成でのオブジェクトの書込みおよび永続化

オブジェクトの書込みおよび永続化
「図2-3 グリッド・キャッシュ構成でのオブジェクトの書込みおよび永続化」の説明

2.3.3 グリッド・キャッシュ構成の例

これらの例のコードは、次のURLで入手できます。

https://toplinkgrid-examples.samplecode.oracle.com/source/browse/*checkout*/toplinkgrid-examples/trunk/downloads/TLG%20JPA%20Example-Grid%20Cache.zip

2.3.3.1 グリッド・キャッシュ構成のキャッシュの構成

例2-1のキャッシュ構成ファイル(coherence-cache-config.xml)は、キャッシュを定義し、ラッパー・シリアライザを構成して関係のシリアライズをサポートします。

例2-1 グリッド・キャッシュ構成のキャッシュの構成

<cache-config>
  <caching-scheme-mapping>
    <cache-mapping>
      <cache-name>*</cache-name>
      <scheme-name>eclipselink-distributed</scheme-name>
    </cache-mapping>
  </caching-scheme-mapping>
  <caching-schemes>
    <distributed-scheme>
      <scheme-name>eclipselink-distributed</scheme-name>
      <service-name>EclipseLinkJPA</service-name>
      <!--
        Configure a wrapper serializer to support serialization of relationships.
      -->
      <serializer>
        <class-name>oracle.eclipselink.coherence.integrated.cache.WrapperSerializer</class-name>
      </serializer>
      <backing-map-scheme>
      <!-- 
        Backing map scheme with no eviction policy. 
      -->
        <local-scheme>
          <scheme-name>unlimited-backing-map</scheme-name>
        </local-scheme>
      </backing-map-scheme>
      </backing-map-scheme>
      <autostart>true</autostart>
    </distributed-scheme>
  </caching-schemes></cache-config>

2.3.3.2 グリッド・キャッシュ構成のエンティティの構成

グリッド・キャッシュを使用するようエンティティを構成するには、例2-2に示すように@Customizer注釈とGridCacheCustomizerクラスを使用します。このクラスは、内部のTopLink GridキャッシュへのすべてのTopLinkコールをインターセプトし、それらをCoherenceキャッシュにリダイレクトします。

例2-2 グリッド・キャッシュ構成のエンティティの構成

import oracle.eclipselink.coherence.integrated.config.GridCacheCustomizer;
import org.eclipse.persistence.annotations.Customizer;

@Entity
@Customizer(GridCacheCustomizer.class)
public class Employee {
...

2.3.3.3 グリッド・キャッシュ構成のオブジェクトの挿入

例2-3では、TopLinkは新しい従業員を作成するために挿入を実行します。エンティティはEntityManagerを通じて永続化され、データベースに配置されます。トランザクションに成功すると、Coherenceキャッシュが更新されます。

例2-3 グリッド・キャッシュ構成のオブジェクトの挿入

EntityManagerFactory emf = Persistence.createEntityManagerFactory("employee-pu");

// Create an employee with an address and telephone number.
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Employee employee = createEmployee();
em.persist(employee);
em.getTransaction().commit();           
em.close();

2.3.3.4 グリッド・キャッシュ構成のオブジェクトの問合せ

例2-4では、指定されたJPQL問合せがデータベースに送られます。問合せ結果はCoherenceキャッシュに照らして解決され、以前にキャッシュされたオブジェクトをビルドするコストが回避されます。

例2-4 グリッド・キャッシュ構成のオブジェクトの問合せ

EntityManagerFactory emf = Persistence.createEntityManagerFactory("employee-pu");

EntityManager em = emf.createEntityManager();
List<Employee> employees = em.createQuery("select e from Employee e where e.lastName = :lastName").setParameter("lastName", "Smith").getResultList();

for (Employee employee : employees) {
   System.err.println(employee);
   for (PhoneNumber phone : employee.getPhoneNumbers()) {
      System.err.println("\t" + phone);
   }
}

emf.close();

2.4 グリッド読取り構成

グリッド読取り構成は、(比較的安定した)大容量のデータに高速にアクセスする必要があり、変更をデータベースに同期的に書き込む必要のあるエンティティに対して使用します。これらのエンティティでは、通常はCoherenceキャッシュへの移入にキャッシュ・ウォーミングが使用されますが、必要に応じて個々の問合せをデータベースに送ることもできます。

一般に、グリッド読取り構成の読取りおよび書込み操作には次の特徴があります。

詳細な例については、「グリッド読取り構成の例」を参照してください。

2.4.1 グリッド読取り構成でのオブジェクトの読取り

グリッド読取り構成では、すべての主キーおよび非主キー問合せがCoherenceキャッシュに送られます。TopLink Gridでは、問合せの処理時間を短縮するために、データ・グリッド全体での問合せのパラレル処理をサポートしています。Coherenceには、オブジェクト形式のデータがすでに含まれており、データベースとの通信やオブジェクト構築で発生するパフォーマンスへの影響を回避します。

グリッド読取り構成を使用する場合、find(...)メソッドによってリクエストされたエンティティがCoherence内に存在しなければ、nullが返されます。ただし、そのエンティティのキャッシュに対してキャッシュ・ローダーが構成されていれば、Coherenceはデータベースからオブジェクトをロードしようとします。これは、主キー問合せにのみ該当します。

キャッシュ・ローダーを構成しても、Coherenceフィルタに変換されるJPQL問合せに影響を与えることはありません。Coherenceはフィルタを使用して検索する際に、キャッシュ内のエンティティ・セットに対してのみ操作を実行するため、データベースは問合せされません。ただし、次の例に示すように、oracle.eclipselink.coherence.integrated.querying.IgnoreDefaultRedirectorクラスを使用して、問合せごとに問合せをCoherenceではなくデータベースに送ることも可能です。

query.setHint(QueryHints.QUERY_REDIRECTOR, new IgnoreDefaultRedirector());

データベース問合せで取得されたオブジェクトはすべて、以降の問合せで使用できるようCoherenceキャッシュに追加されます。この構成はデフォルトで、Coherenceを介してエンティティに対するすべての問合せを解決するため、Coherenceのキャッシュをすべての問合せ対象のデータでウォーミングする必要があります。

グリッド読取り構成では、単一のエンティティ・タイプからデータを抽出する予測問合せ(レポート)もCoherenceに送られます。たとえば、次のJPQL問合せは、Coherenceキャッシュに含まれるすべての従業員の姓名を返します。

select e.firstName, e.lastName from Employee e

このタイプの問合せは、ユーザー・インタフェースにドロップダウン・リストを移入するときなど、エンティティ全体が必要ではない場合に役立ちます。

EclipseLink JPAはすべてのデータベース更新を実行してから更新されたオブジェクトをCoherenceに伝播するため、キャッシュ・ストアはグリッド読取り構成と互換性がありません。キャッシュ・ストアを使用する場合、Coherenceはオブジェクトの書込みを再試行します。

EclipseLink JPAの問合せのヒントの使用方法の詳細は、次のURLにあるEclipseLink のドキュメントを参照してください。

http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_(ELUG)#How_to_Use_EclipseLink_JPA_Query_Hints

図2-4に、グリッド読取り構成での問合せのパスを示します。

  1. アプリケーションがJPQL問合せを発行します。

  2. TopLinkはCoherenceキャッシュに対してフィルタを実行します。

  3. TopLinkはCoherenceキャッシュからの結果のみを返します。データベースは問合せされません。

図2-4 問合せを使用したオブジェクトの読取り

オブジェクトの読取り
「図2-4 問合せを使用したオブジェクトの読取り」の説明

2.4.2 グリッド読取り構成でのオブジェクトの書込み

グリッド読取り構成では、TopLinkがすべてのデータベース書込み操作(挿入、更新、削除)を直接実行します。その後、Coherenceキャッシュがデータベースへの変更を反映するように更新されます。TopLinkには、大量のデータを書き込む際のパフォーマンス機能が数多く用意されています。これらには、バッチ書込み、パラメータ・バインディング、ストアド・プロシージャ・サポート、データベース制約を満たすための文の順序付けなどがあります。

このアプローチは、長所を最大限に生かすことができます。1つはデータベースの更新が効率的に行われること、そしてもう1つはCoherenceのデータ・グリッド全体に対して問合せをパラレルに実行できることで、さらに個々の問合せをデータベースに直接送ることもできます。

図2-5に、グリッド読取り構成でのオブジェクトの書込みと永続化のパスを示します。

  1. アプリケーションがcommit問合せを発行します。

  2. TopLinkがデータベースを更新します。

  3. トランザクションが正常に完了すると、TopLinkはCoherenceキャッシュを更新します。

図2-5 グリッド読取り構成でのオブジェクトの書込みおよび永続化

オブジェクトの書込みおよび永続化
「図2-5 グリッド読取り構成でのオブジェクトの書込みおよび永続化」の説明

2.4.3 グリッド読取り構成の例

これらの例のコードは、次のURLで入手できます。

https://toplinkgrid-examples.samplecode.oracle.com/source/browse/*checkout*/toplinkgrid-examples/trunk/downloads/TLG%20JPA%20Example-Grid%20Read.zip

2.4.3.1 グリッド読取り構成のキャッシュの構成

例2-5のキャッシュ構成ファイル(coherence-cache-config.xml)は、キャッシュを定義し、ラッパー・シリアライザを構成して関係のシリアライズをサポートします。oracle.eclipselink.coherence.integrated.EclipseLinkJPACacheLoaderクラスは、キャッシュ・ストア・スキームを定義します。

例2-5 グリッド読取り構成のキャッシュの構成

<cache-config>
  <caching-scheme-mapping>
    <cache-mapping>
      <cache-name>*</cache-name>
      <scheme-name>eclipselink-distributed-readonly</scheme-name>
    </cache-mapping>
  </caching-scheme-mapping>
  <caching-schemes>
    <distributed-scheme>
      <scheme-name>eclipselink-distributed-readonly</scheme-name>
      <service-name>EclipseLinkJPAReadOnly</service-name>
      <!--
        Configure a wrapper serializer to support serialization of relationships.
      -->
      <serializer>
        <class-name>oracle.eclipselink.coherence.integrated.cache.WrapperSerializer</class-name>
      </serializer>
      <backing-map-scheme>
        <read-write-backing-map-scheme>
          <internal-cache-scheme>
            <local-scheme />
          </internal-cache-scheme>
          <!-- 
            Define the cache scheme. 
          -->
          <cachestore-scheme>
            <class-scheme>
              <class-name>oracle.eclipselink.coherence.integrated.EclipseLinkJPACacheLoader</class-name>
              <init-params>
                <param-type>java.lang.String</param-type>
                <param-value>{cache-name}</param-value>
              </init-param>
                <init-param>
                  <param-type>java.lang.String</param-type>
                  <param-value>employee-pu</param-value>
                </init-param>
              </init-params>
            </class-scheme>
          </cachestore-scheme>
          <read-only>true</readonly>
        </read-write-backing-map-scheme>
      </backing-map-scheme>
      <autostart>true</autostart>
    </distributed-scheme>
  </caching-schemes></cache-config>

2.4.3.2 グリッド読取り構成のオブジェクトの読取り

Coherenceキャッシュを読み取るようにエンティティを構成するには、例2-6に示すように@Customizer注釈とCoherenceReadCustomizerクラスを使用します。

例2-6 グリッド読取り構成のエンティティの構成

import oracle.eclipselink.coherence.integrated.config.CoherenceReadCustomizer;
import org.eclipse.persistence.annotations.Customizer;

@Entity
@Customizer(CoherenceReadCustomizer.class)
public class Employee {
...
}

2.4.3.3 グリッド読取り構成のオブジェクトの挿入

例2-7では、TopLinkは挿入を実行して新しい従業員を作成しています。トランザクションが正常に完了すると、新しいオブジェクトがその主キーによってCoherenceキャッシュに挿入されます。

例2-7 グリッド読取り構成のオブジェクトの挿入

EntityManagerFactory emf = Persistence.createEntityManagerFactory("employee-pu");
// Create an employee with an address and telephone number
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Employee employee = createEmployee();
em.persist(employee);
em.getTransaction().commit();
em.close();

emf.close();

2.4.3.4 グリッド読取り構成のオブジェクトの問合せ

従業員を検索する際に、読取り問合せがCoherenceキャッシュに送られます。例2-8に示すように、JPQL問合せがCoherenceフィルタに変換されます。

例2-8 グリッド読取り構成のオブジェクトの問合せ

EntityManagerFactory emf = Persistence.createEntityManagerFactory("employee-pu");
EntityManager em = emf.createEntityManager();
List<Employee> employees = em.createQuery("select e from Employee e where e.lastName = :lastName").setParameter("lastName", "Smith").getResultList();
  for (Employee employee : employees) {
    System.err.println(employee);
      for (PhoneNumber phone : employee.getPhoneNumbers()) {
        System.err.println("\t" + phone);
      }
  }emf.close();

特定のID(キー)を使用してCoherenceキャッシュからオブジェクトを取得するには、em.find(Entity.class, ID)メソッドを使用します。指定したIDを持つオブジェクトがキャッシュに存在しない場合は、データベースを問い合せるようCoherenceキャッシュ・ローダーを構成して、オブジェクトを検出することもできます。

2.5 グリッド・エンティティ構成

グリッド・エンティティ構成は、(比較的安定した)大容量のデータに高速にアクセスする必要があり、実行される更新が比較的少ないアプリケーションに対して使用してください。ライトビハインドを使用してこの構成をCoherenceキャッシュ・ストアと組み合せると、データベース更新を非同期に実行することにより、アプリケーションのレスポンス時間を向上させることができます。

一般に、グリッド・エンティティ構成の読取りおよび書込み操作には次の特徴があります。

詳細な例については、「グリッド・エンティティ構成の例」を参照してください。

2.5.1 グリッド・エンティティ構成でのオブジェクトの読取り

グリッド・エンティティ構成でのオブジェクトの問合せは、グリッド読取り構成と同じです。詳細は、「グリッド・キャッシュ構成でのオブジェクトの読取り」を参照してください。

2.5.2 グリッド・エンティティ構成でのオブジェクトの書込み

グリッド・エンティティ構成では、EntityManagerインスタンスを介して永続化、更新またはマージされたオブジェクトはすべて、適切なCoherenceキャッシュに挿入されます。Coherenceキャッシュ内のオブジェクトをデータベースに対して永続化するには、キャッシュごとにEclipseLink JPAキャッシュ・ストア(oracle.eclipselink.coherence.integrated.EclipseLinkJPACacheStore)を構成する必要があります。

ライトビハインドを使用して更新済のオブジェクトの一括書込みを非同期的に行うよう、キャッシュ・ストアを構成することもできます。詳細は、Coherenceの開発者ガイドを参照してください。

図2-6に、グリッド・エンティティ構成でのオブジェクトの書込みと永続化のパスを示します。

  1. アプリケーションがcommitコールを発行します。

  2. TopLinkはすべての問合せを送って、Coherenceキャッシュを更新します。

  3. Coherenceのキャッシュ・ストアを構成すると(オプション)、TopLinkはデータベースも更新します。

図2-6 グリッド・エンティティ構成でのオブジェクトの書込みおよび永続化

オブジェクトの書込みおよび永続化です。
「図2-6 グリッド・エンティティ構成でのオブジェクトの書込みおよび永続化」の説明

2.5.3 グリッド・エンティティ構成でのオブジェクトの書込みに対する制約

キャッシュ・ストアを使用する場合、Coherenceはすべての書込み操作が成功することを前提とするため、TopLinkに失敗を通知しません。このため、Coherenceキャッシュがデータベースの内容と異なることがあります。Coherenceとサード・パーティ製アプリケーションによってデータベースが同時に更新された場合に発生する可能性のあるデータの破損から保護するためにオプティミスティック・ロックを使用することはできません。

Coherenceキャッシュ・メンバーがデータベースに更新を書き込む順序は予測できないため、参照整合性は保証できません。参照整合性制約はデータベースから削除する必要があります。そうしないと、書込み操作が次のエラーで失敗することがあります。

org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.BatchUpdateException: ORA-02292: integrity constraint violated - child record found
Error Code: 2292

2.5.4 グリッド・エンティティ構成の例

これらの例のコードは、次のURLで入手できます。

https://toplinkgrid-examples.samplecode.oracle.com/source/browse/*checkout*/toplinkgrid-examples/trunk/downloads/TLG%20JPA%20Example-Grid%20Entity.zip

2.5.4.1 グリッド・エンティティ構成のキャッシュの構成

例2-9のキャッシュ構成ファイル(coherence-cache-config.xml)は、ラッパー・シリアライザを構成して関係のシリアライズをサポートします。oracle.eclipselink.coherence.integrated.EclipseLinkJPACacheStoreクラスは、キャッシュ・ストア・スキームを定義します。

例2-9 グリッド・エンティティ構成のキャッシュの構成

<cache-config>
  <caching-scheme-mapping>
    <cache-mapping>
      <cache-name>*</cache-name>
      <scheme-name>eclipselink-distributed-readwrite</scheme-name>
    </cache-mapping>
  </caching-scheme-mapping>
  <caching-schemes>
    <distributed-scheme>
      <scheme-name>eclipselink-distributed-readwrite</scheme-name>
      <service-name>EclipseLinkJPAReadWrite</service-name>
      <!--
        Configure a wrapper serializer to support serialization of relationships.
      -->
      <serializer>
        <class-name>oracle.eclipselink.coherence.integrated.cache.WrapperSerializer</class-name>
      </serializer>
      <backing-map-scheme>
       <read-write-backing-map-scheme>
        <internal-cache-scheme>
          <local-scheme />
          </internal-cache-scheme>
           <!-- 
             Define the cache scheme 
           -->
            <cachestore-scheme>
              <class-scheme>
                <class-name>oracle.eclipselink.coherence.integrated.EclipseLinkJPACacheStore</class-name>
                <init-params>
                  <init-param>
                    <param-type>java.lang.String</param-type>
                    <param-value>{cache-name}</param-value>
                  </init-param>
                  <init-param>
                    <param-type>java.lang.String</param-type>
                    <param-value>employee-pu</param-value>
                  </init-param>
                </init-params>
              </class-scheme>
            </cachestore-scheme>
        </read-write-backing-map-scheme>
      </backing-map-scheme>
      <autostart>true</autostart>
    </distributed-scheme>
  </caching-schemes>
</cache-config>

2.5.4.2 グリッド・エンティティ構成のエンティティの構成

Coherenceを読み取るようにエンティティを構成するには、例2-10に示すように@Customizer注釈とCoherenceReadWriteCustomizerクラスを使用します。

例2-10 グリッド・エンティティ構成のエンティティの構成

import oracle.eclipselink.coherence.integrated.config.CoherenceReadWriteCustomizer;
import org.eclipse.persistence.annotations.Customizer;

@Entity
@Customizer(CoherenceReadWriteCustomizer.class)
public class Employee {
...
}

2.5.4.3 グリッド・エンティティ構成のオブジェクトの永続化

例2-11では、TopLinkは挿入を実行して新しい従業員を作成しています。エンティティはEntityManagerインスタンスによって永続化され、適切なCoherenceキャッシュに挿入されます。

例2-11 グリッド・エンティティ構成のオブジェクトの永続化

EntityManagerFactory emf = Persistence.createEntityManagerFactory("employee-pu");

// Create an employee with an address and telephone number.
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Employee employee = createEmployee();
em.persist(employee);
em.getTransaction().commit();           
em.close();

2.5.4.4 グリッド・エンティティ構成のオブジェクトの問合せ

例2-12に示すように、従業員を検索する際に、読取り問合せがCoherenceキャッシュに送られます。

例2-12 グリッド・エンティティ構成のオブジェクトの問合せ

EntityManagerFactory emf = Persistence.createEntityManagerFactory("employee-pu");

EntityManager em = emf.createEntityManager();
List<Employee> employees = em.createQuery("select e from Employee e where e.lastName = :lastName").setParameter("lastName", "Smith").getResultList();

for (Employee employee : employees) {
   System.err.println(employee);
   for (PhoneNumber phone : employee.getPhoneNumbers()) {
      System.err.println("\t" + phone);
   }
}

emf.close();

特定のID(キー)を使用してCoherenceキャッシュからオブジェクトを取得するには、em.find(Entity.class, ID)メソッドを使用します。指定したIDを持つオブジェクトがキャッシュに存在しない場合は、データベースを問い合せるようCoherenceキャッシュ・ストアを構成して、オブジェクトを検出することもできます。

2.6 グリッド読取りおよびグリッド・エンティティのフェイルオーバーの処理

グリッド読取り構成とグリッド・エンティティ構成では、TopLink GridはJPQL問合せからCoherenceフィルタへの変換とグリッドでの問合せの実行を試行します。ただし、一部の問合せはフィルタに変換できません。TopLink Gridは、このような問合せを検出すると、データベースに自動的にフェイルオーバーして問合せを実行します。TopLinkでは、JPQLからフィルタへの変換に失敗した場合に呼び出されるユーザー定義の変換失敗委任オブジェクトを指定できます。変換失敗委任は、eclipselink.coherence.query.translation-failure-delegate永続性ユニット・プロパティを宣言することで構成します。例:

<property name="eclipselink.coherence.query.translation-failure-delegate" value="org.example.ExceptionFailoverPolicy"/>

変換失敗委任では、translationFailed(DatabaseQuery query, Record arguments, Session session)という単一のメソッドを定義するoracle.eclipselink.coherence.integrated.querying.TranslationFailureDelegateクラスを実装する必要があります。

2.7 エンティティ・リレーションシップのラップとアンラップ

リレーションシップとともにエンティティをCoherenceキャッシュに格納するとき、TopLink Gridは、リレーションシップ情報を維持するラッパー・クラスを生成します。この方法で、オブジェクトが(eagerまたはlazyで)Coherenceキャッシュから読み取られるときにリレーションシップを解決できます。

Coherence APIを使用してエンティティをCoherenceキャッシュから直接読み取ると、ラッパーは自動的には削除されません。例2-13に示すように、シリアライザでsetNotEclipseLink(true)メソッドを呼び出すことによりプログラムで自動アンラップを構成できます。また、システム・プロパティをeclipselink.coherence.not-eclipselinkとして設定して、エンティティを自動的にアンラップすることもできます。

正しく構成されると、キャッシュget操作はアンラップされたエンティティを返します。

例2-13 エンティティのアンラップ

WrapperSerializer wrapperSerializer = (WrapperSerializer)myCache.getCacheService().getSerializer();
wrapperSerializer.setNotEclipseLink(true); // So the Serializer will unwrap an Entity when clients use a get() call from the cache.

2.8 問合せの操作

この項では、次のトピックについて説明します。

2.8.1 IDによるオブジェクトの問合せ

特定のID(キー)を使用してCoherenceキャッシュからエンティティを取得するには、em.find(Entity.class, ID)メソッドを使用します。たとえば、次のコードはキー8のエンティティをCoherence Employeeキャッシュから取得します。

em.find(Employee.class, 8) 

エンティティがCoherenceキャッシュ内に見つからない場合、TopLinkはデータベースに対してSELECT文を実行します。結果が見つかると、エンティティが構成されてCoherenceに挿入されます。問合せに固有の動作は、Coherenceキャッシュ構成によって決まります。

  • グリッド・キャッシュ構成findメソッドを呼び出すと、キャッシュ・ミス時にデータベースに対してSELECT文が実行され、キャッシュが更新されます。

  • グリッド読取り構成またはグリッド・エンティティ構成findメソッドを呼び出すと、Coherenceキャッシュに対してget操作が実行されます。キャッシュ・ミスの場合は、CacheLoaderインスタンス(構成されている場合)を使用してデータベースに対してSELECT文が実行されます。

2.8.2 基準を使用したオブジェクトの問合せ

特定の選択基準と一致するエンティティを取得するには、em.createQuery("...")メソッドを使用します。問合せ固有の動作は、Coherenceキャッシュ構成によって決まります。

  • グリッド・キャッシュ構成では、問合せは常にデータベースに対してSELECT文を実行します。たとえば、次のコードはSELECT文を実行してJohnという名前の従業員を検索します。

    em.createQuery("select e from Employee e where e.name='John'")
    
  • グリッド読取り構成グリッド・エンティティ構成では、問合せはCoherenceキャッシュに対して実行されます。キャッシュに選択基準と一致するエンティティが存在しない場合は、何も返されません。これは、問合せを実行する前にキャッシュをウォーミングする必要のある理由の一例です。

  • キャッシュ・ストアとキャッシュ・ローダーでは、問合せは主キーに対してのみ実行されます。

2.8.3 問合せでの索引の使用

索引を使用すると、値(またはそれらの値の属性)および対応するキーをキャッシュ内で関連付けて、問合せのパフォーマンスを向上させることができます。TopLink Gridでは、@Property注釈で索引を宣言できます。IntegrationPropertiesクラスはINDEXEDプロパティを提供します。

例2-14@Property注釈は、name属性が索引付けされることを宣言しています。TopLink Gridは、Publisherキャッシュ内のその属性の索引を定義します。

例2-14 TopLink GridへのCoherence問合せ索引の公開

import static oracle.eclipselink.coherence.IntegrationProperties.INDEXED;
import oracle.eclipselink.coherence.integrated.config.CoherenceReadCustomizer;
 
@Customizer(CoherenceReadCustomizer.class)
public class Publisher implements Serializable {
...
    @Property(name=INDEXED, value="true")
    private String name;
 ...

索引が付けられたら、次のようなJPQL問合せを発行して、キャッシュ内の名前がSで始まるすべてのPublishersを返すことができます。

SELECT Publisher p WHERE p.name like 'S%' 

内部的には、Coherenceはグリッドに格納されているすべてのPublisherオブジェクトをデシリアライズして検証するかわりにname索引を調べて一致を探すことで問合せを処理します。デシリアライズを回避することで、問合せの実行時間が大幅に向上し、一時的にデシリアライズされたオブジェクトのガベージ・コレクションが不要になり、CPU使用量が削減されます。

2.8.4 問合せに対する制約

Coherenceキャッシュの問合せには次の制約があります。

  • Coherenceのフィルタ・フレームワークは単一キャッシュに制限されているため、JPQLのjoin問合せをフィルタに変換することはできません。すべてのjoin問合せはデータベースに対して実行されます。

  • このリリースのTopLink Gridでは、JPQLバルク更新および削除をサポートしていません。