JPAEntityLoader プラグイン

JPAEntityLoader プラグインは、EntityManager API を使用する場合に Java Persistence API (JPA) を使用してデータベースと通信する組み込みローダー実装です。 ObjectMap API を使用する場合は、JPALoader ローダーを使用します。

ローダーの詳細

ObjectMap API を使用してデータを保管する場合、JPALoader プラグインを使用します。 EntityManager API を使用してデータを保管する場合、JPAEntityLoader プラグインを使用します。

ローダーでは、2 つの主要な関数を提供しています。
  1. get: get メソッドでは、JPAEntityLoader プラグインは、まず、javax.persistence.EntityManager.find(Class entityClass, Object key) メソッドを呼び出し、JPA エンティティーを検索します。次にこの JPA エンティティーをエンティティー・タプルに射影します。射影時には、タプル属性とアソシエーション・キーの両方が値タプルに保管されます。各キーの処理後、get メソッドは、エンティティー値タプルのリストを返します。
  2. batchUpdate: batchUpdate メソッドでは、LogElement オブジェクトのリストを含む LogSequence オブジェクトを使用します。 各 LogElement オブジェクトには、キー・タプルと値タプルが含まれています。JPA プロバイダーと対話するため、まず、キー・タプルに基づいて eXtreme Scale エンティティーを検出する必要があります。LogElement タイプに基づいて、以下の JPA 呼び出しを実行します。
    • insert: javax.persistence.EntityManager.persist(Object o)
    • update: javax.persistence.EntityManager.merge(Object o)
    • remove: javax.persistence.EntityManager.remove(Object o)
タイプが update の LogElement は、JPAEntityLoader に javax.persistence.EntityManager.merge(Object o) メソッドを呼び出させ、エンティティーをマージします。しかし、update タイプの LogElement は、com.ibm.websphere.objectgrid.em.EntityManager.merge(object o) 呼び出しか、eXtreme Scale EntityManager 管理インスタンスの属性変更のいずれかの結果である可能性があります。以下の例を参照してください。
com.ibm.websphere.objectgrid.em.EntityManager em = og.getSession().getEntityManager();
em.getTransaction().begin();
Consumer c1 = (Consumer) em.find(Consumer.class, c.getConsumerId());
c1.setName("New Name");
em.getTransaction().commit();

この例では、update タイプの LogElement が、マップ・コンシューマーの JPAEntityLoader に送られます。 JPA 管理エンティティーに対しては属性更新が呼び出されますが、JPA エンティティー・マネージャーに対しては javax.persistence.EntityManager.merge(Object o) メソッドが呼び出されます。この変更された振る舞いのため、このプログラミング・モデルの使用にはいくつかの制限があります。

アプリケーション設計の規則

エンティティーには、他のエンティティーとのリレーションシップがあります。リレーションシップが含まれ、JPAEntityLoader がプラグインされているアプリケーションを設計する場合、さらなる考慮が必要です。アプリケーションは、以下のセクションに記載しているように、次の 4 つの規則に従う必要があります。

リレーションシップの深さのサポートの制限

JPAEntityLoader がサポートされるのは、リレーションシップのないエンティティー、または 1 レベルのリレーションシップのエンティティーを使用する場合に限られます。Company > Department > Employee など、複数レベルのリレーションシップはサポートされません。

マップごとに 1 つのローダー

Consumer-ShippingAddress エンティティーのリレーションシップを例に使用して、EAGER フェッチを使用可能にして、1 件の consumer をロードする場合、すべての関連 ShippingAddress オブジェクトをロードできます。Consumer オブジェクトを永続化またはマージする場合、cascade-persist または cascade-merge が有効化されている場合は、関連する ShippingAddress オブジェクトを永続化またはマージできます。

Consumer エンティティー・タプルを保管するルート・エンティティーのローダーをプラグインすることはできません。各エンティティー・マップごとに 1 つのローダーを構成する必要があります。

JPA と eXtreme Scale に同じカスケード・タイプを設定

改めてエンティティー Consumer が ShippingAddress と 1 対多のリレーションシップがあるシナリオを考えます。このリレーションシップに cascade-persist が有効化されたシナリオを見てみます。Consumer オブジェクトが eXtreme Scale にパーシストされる場合、関連する N 個の ShippingAddress オブジェクトも eXtreme Scale にパーシストされます。

ShippingAddress に対して cascade-persist リレーションシップがある Consumer オブジェクトの persist 呼び出しは、JPAEntityLoader 層により 1 つの javax.persistence.EntityManager.persist(consumer) メソッド呼び出しと N 個の javax.persistence.EntityManager.persist(shippingAddress) メソッド呼び出しに変換されます。しかし、ShippingAddress オブジェクトに対するこれら N 個の余分の persist 呼び出しは、JPA プロバイダーの観点からは、cascade-persist 設定のため不必要です。この問題を解決するため、eXtreme Scale では、新たなメソッド isCascaded を LogElement インターフェースに提供しています。isCascaded メソッドは、LogElement が eXtreme Scale EntityManager のカスケード操作の結果であるかどうかを示します。この例では、ShippingAddress マップの JPAEntityLoader は、cascade persist 呼び出しにより N 個の LogElement オブジェクトを受け取ります。JPAEntityLoader は、isCascaded メソッドが true を返すことを検出し、JPA 呼び出しを行わずにこれらを無視します。したがって、JPA の観点からは、1 つの javax.persistence.EntityManager.persist(consumer) メソッド呼び出しのみを受け取ります。

カスケードを有効にしてエンティティーをマージしたり、エンティティーを除去する場合、同じ振る舞いが示されます。カスケードされた操作は、JPAEntityLoader プラグインによって無視されます。

カスケード・サポートの設計では、JPA プロバイダーに対して eXtreme Scale EntityManager 操作をやり直すことになります。これらの操作には、パーシスト、マージ、および除去操作があります。カスケード・サポートを使用可能にするには、JPA のカスケード設定と eXtreme Scale EntityManager が同じであることを確認してください。

エンティティー更新の使用は注意すること

前述のようにカスケード・サポートの設計では、JPA プロバイダーに対して eXtreme Scale EntityManager 操作をやり直すことになります。アプリケーションが eXtreme Scale EntityManager に対して ogEM.persist(consumer) メソッドを呼び出す場合、cascade-persist 設定のために関連の ShippingAddress オブジェクトがパーシストされていても、JPAEntityLoader は JPA プロバイダーに対して jpAEM.persist(consumer) メソッドのみを呼び出します。

ただし、アプリケーションが管理エンティティーを更新する場合、この更新は JPAEntityLoader プラグインによる JPA merge 呼び出しに変換されます。このシナリオでは、複数レベルのリレーションシップおよびキー・アソシエーションのサポートは保証されません。この場合、ベスト・プラクティスは、管理エンティティーを更新する代わりに javax.persistence.EntityManager.merge(o) メソッドを使用することです。