最終ドラフト提案の段階になった Java Persistence API(JPA) バージョン2.0は、クライテリアクエリのAPIとメタモデルAPIとBean Validation[JSR 303]のサポートを追加する重要な仕様への更新だ。
JPA実装が解析する文字列に埋め込まれたJPA-QLの代わりに、クライテリアクエリAPIではJavaオブジェクトのメソッドを呼び出すことでクエリの作成ができる。最初の公開ドラフトでは、文字列ベースのAPIしかなかった。そのため、提案に対する型安全性を向上する可能性を探るように勧める、多くのフィードバックがExpert Groupに寄せられた。Gavin King氏は、既存の文字列ベースのAPIの上に構築し、アプリケーションにおけるそれぞれの永続クラスのメタモデルの型を自動的に生成するのに、Java 6付属のjavax.annotation.Processorを利用するという、提案に応じた。 Genericsと組み合わせて、このメカニズムは、クラスのメソッドとフィールドのための型安全なメタモデルがJavaで不足してることへの、実効的な回避策を提供する。理解することがかなり困難で、一般的に特定のIDEサポートを要求するコードを生成する傾向があるので、コードジェネレータが使われるといつも賛否両論となる。けれどもこの場合は、型情報のためだけにコードが生成されるので、コードをかなりきれいに保つことができる。例えば、次のような永続クラスが与えられると、
import java.util.Set;
import java.math.BigDecimal;
@Entity public class Order {
@Id Integer orderId;
@ManyToOne Customer customer;
@OneToMany Set
Address shippingAddress;
BigDecimal totalCost;
...
}
対応する正規化されたメタモデルクラス、Order_ は以下のようになる。
import java.math.BigDecimal;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.Set;
import javax.persistence.metamodel.TypeSafeMetamodel;
import javax.annotation.Generated;
@Generated
@TypeSafeMetamodel
public class Order_ {
public static volatile Attribute<Order, Integer> orderId;
public static volatile Attribute<Order, Customer> customer;
public static volatile Set<Order, Item> lineitems;
public static volatile Attribute<Order, Address> shippingAddress;
public static volatile Attribute<Order, BigDecimal> totalCost;
}
アノテーションプロセッサはJava 6に含まれているので、この変更は特定のIDEサポートも必要としない。– IDEはコンパイラによって起動されるアノテーションプロセッサに委譲でき、メタモデルはオンザフライに生成される。
メタモデルの永続状態と永続ユニット(persistence unit)の管理対象クラスの関連へ、動的にアクセスするインタフェースの仕様を定めた、API経由でメタモデルは検索される。 オブジェクト/リレーショナルマッピング情報へのアクセスはまだサポートされていないが、将来のアップデートで計画されている。 インタフェースは永続プロバイダによって実装され、EntityManagerFactory.getMetamodel と EntityManager.getMetamodelメソッド経由でアクセスできる。これらのメソッドは、javax.persistence.metamodel.Metamodelインタフェースを実装する、永続プロバイダの実装クラスを返す。
King氏は、CriteriaQueryとQueryの両方に型パラメータを追加することでクエリ結果セットへの型安全性を拡張する、さらなるリファクタリングを最近提案した。 これにより、型安全なリストのエントリやラッパーへの直接アクセスを開発者に提供する。しかし現在javax.persistence.Queryは型パラメータを持っていないので、JPA 1.0ベースのプロジェクトではコンパイラー警告を起こしてしまう。
型安全アプローチはExper Group内でもよく議論となりがちだった。 文字列と型安全アプローチとの比較について、JPA2.0仕様のリードであるLinda DeMichiel氏は、彼女のブログで以下のように書いている。
"文字列ベースのAPIと比較したメタモデルベースのAPIについてのプラスとマイナスを多く議論した後、私たち[Expert Group]は型安全APIを採用することを決定しました。しかし開発者が望むなら、文字列ベースのアプローチを使うことができるオプションを用意しました。"
二つのオプションの主な違いは、文字列ベースの属性名は、JOINやナビゲーションの属性参照を指定する方法として使われることだ。結果的にクエリは、型安全バージョンと同じ意味を持つが、同じレベルの型安全性は無い。
JPA 2.0は Java PersistenceアプリケーションにおけるBean Validation [JSR 303] 利用のサポートも定義している。管理対象クラス (エンティティ、マップされたスーパクラス、埋め込み可能なクラス) は、Bean Validation制約に設定することができる。pre-persist、pre-update、pre-removeのエンティティライフサイクルイベント上のBean Validation実装に、Java Persistenceアプリケーションが妥当性確認を委譲することを指定することにより、これらの制約を利用する自動妥当性確認は実現される。
Expert Groupはコミュニティからのフィードバックを待ち望んでいる。フィードバックはjsr-317-pfd-feedback@sun.com に送ることができる。