JPA ローダーのプログラミング考慮事項

Java Persistence API (JPA) ローダーは、JPA を使用してデータベースと対話する Loader プラグイン実装です。JPA ローダーを使用するアプリケーションの開発時には、以下の考慮事項に注意してください。

eXtreme Scale エンティティーと JPA エンティティー

eXtreme Scale エンティティー・アノテーション、XML 構成、あるいはその両方を使用して、POJO クラスを eXtreme Scale エンティティーに指定することができます。また、JPA エンティティー・アノテーション、XML 構成、あるいはその両方を使用して、同じ POJO クラスを JPA エンティティーに指定することもできます。

eXtreme Scale エンティティー: eXtreme Scale エンティティーは、ObjectGrid マップに保管された永続データを表します。エンティティー・オブジェクトはキー・タプルおよび値タプルに変換され、キーと値のペアとしてマップに保管されます。 タプルとは、画素属性の配列です。

JPA エンティティー: JPA エンティティーは、コンテナー管理パーシスタンスを使用して自動的にリレーショナル・データベースに保管された永続データを表します。データは、例えば、データベース内のデータベース・タプルのように、何らかのデータ・ストレージ・システム形式内の適切な形式で永続化されます。

eXtreme Scale エンティティーが永続化される場合、その関係は別のエンティティー・マップに保管されます。例えば、ShippingAddress エンティティーと 1 対多の関係にある Consumer エンティティーを永続化する場合、cascade-persist が有効になっている場合、ShippingAddress エンティティーは、タプル形式で shippingAddress マップに保管されます。JPA エンティティーを永続化する場合、JPA エンティティーも、cascade-persist が有効になっている場合、データベース表に対して永続化されます。 POJO クラスが、eXtreme Scale エンティティーと JPA エンティティーの両方として指定される場合、データは ObjectGrid エンティティー・マップとデータベースの両方に対して永続化できます。一般的な使用は以下のようになります。
  • プリロード・シナリオ: JPA プロバイダーを使用してエンティティーがデータベースからロードされ、これを ObjectGrid エンティティー・マップに永続化します。
  • ローダー・シナリオ: ローダー実装が、ObjectGrid エンティティー・マップに対してプラグインされ、ObjectGrid エンティティー・マップに保管されたエンティティーが JPA プロバイダーを使用してデータベースに対して永続化され、またはこれをデータベースからロードできるようにします。

また、POJO クラスが JPA エンティティーのみとして指定されることも一般的です。その場合、ObjectGrid マップに保管されるのは POJO インスタンスで、これに対してエンティティー・タプルは ObjectGrid エンティティー・ケースに保管されます。

エンティティー・マップに関するアプリケーション設計の考慮事項

JPALoader インターフェースをプラグインする場合、オブジェクト・インスタンスは直接 ObjectGrid マップに保管されます。

しかし、JPAEntityLoader をプラグインする場合、エンティティー・クラスは、eXtreme Scale エンティティーと JPA エンティティーの両方として指定されます。その場合、このエンティティーには、ObjectGrid エンティティー・マップと JPA パーシスタンス・ストアの 2 つの永続ストアがあるものとしてこれを取り扱います。アーキテクチャーは、JPALoader の場合よりも複雑になります。

JPAEntityLoader プラグインおよびアプリケーション設計の考慮事項に関して詳しくは、JPAEntityLoader プラグインを参照してください。エンティティー・マップに独自のローダーを実装する予定の場合にも、この情報が参考になります。

パフォーマンスの考慮事項

リレーションシップに対して適切な EAGER または LAZY のフェッチ・タイプを必ず設定してください。 例えば、パフォーマンスの違いを説明するため、OpenJPA による 1 対多の双方向リレーションシップ Consumer と ShippingAddress を参考にします。 この例では、JPA 照会では select o from Consumer o where . . . を実行して、バルク・ロードを行い、さらに関連するすべての ShippingAddress オブジェクトをロードしようとします。Consumer クラスに定義される 1 対多のリレーションシップは以下のようになります。

@Entity
public class Consumer implements Serializable {

    @OneToMany(mappedBy="consumer",cascade=CascadeType.ALL, fetch =FetchType.EAGER) 
    ArrayList <ShippingAddress> addresses;

ShippingAddress クラスに定義された多対 1 の関係 consumer を以下に示します。

@Entity
public class ShippingAddress implements Serializable{

    @ManyToOne(fetch=FetchType.EAGER)
    Consumer consumer;
}

どちらのリレーションシップのフェッチ・タイプも EAGER で構成されている場合、OpenJPA では、N+1+1 の照会を使用してすべての Consumer オブジェクトおよび ShippingAddress オブジェクトを取得します。ここで、N は ShippingAddress オブジェクトの数です。しかし、次のように ShippingAddress が LAZY のフェッチ・タイプを使用するように変更されると、2 つだけの照会を使用してすべてのデータを取得します。

@Entity
public class ShippingAddress implements Serializable{

    @ManyToOne(fetch=FetchType.LAZY)
    Consumer consumer;
}

照会は同じ結果を返しますが、 照会の数が少なくなると、データベースとの相互作用が著しく減り、その結果、アプリケーション・パフォーマンスが向上する可能性があります。