JSRs: Java Specification Requests - JSR 338: JavaTM Persistence 2.1
http://jcp.org/en/jsr/detail?id=338
JSR-000344 JavaServerTM Faces 2.2
http://jcp.org/aboutJava/communityprocess/edr/jsr344/
JSR-000339 JavaTM API for RESTful Web Services (JAX-RS) 2.0
http://jcp.org/aboutJava/communityprocess/edr/jsr339/index.html
JSR-000346 Contexts and Dependency Injection for JavaTM EE 1.1
http://jcp.org/aboutJava/communityprocess/edr/jsr346/index.html
JPA 2.1のキモとなる部分はこちら。
- ストアドプロシージャのサポート
事前定義済みのデータベース関数やユーザー定義のデータベース関数の呼び出しのサポートがJava Persistence query languageに追加されました。
ストアドプロシージャを実行するためのStoredProcedureQuery
を返すEntityManager.createXXXStoredProcedureQuery
メソッドには様々な亜種があります。@NamedQuery
のように、ストアドプロシージャ、引数、および結果のデータ型を指定し、命名する@NamedStoredProcedureQuery
があります。エンティティやマッピングされたスーパークラスにこのアノテーションを指定できます。アノテーションで指定された名前は、EntityManager.createNamedStoredProcedureQuery
で使われます。IN、OUT、INOUTの引数を指定して、プロシージャからかえってくる値を取り出すことができます。以下はその例です。
@Entity
@NamedStoredProcedureQuery(name="topGiftsStoredProcedure", procedureName="Top10Gifts")
public class Product {
. . .
}
// クライアント側では…
StoredProcedreQuery query = EntityManager.createNamedStoredProcedureQuery("topGiftsStoredProcedure");
query.registerStoredProcedureParameter(1, String.class, ParameterMode.INOUT);
query.setParameter(1, "top10");
query.registerStoredProcedureParameter(2, Integer.class, ParameterMode.IN);
query.setParameter(2, 100);
// there are other setParameter methods for defining the temporal type of a parameter
. . .
query.execute();
String response = query.getOutputParameterValue(1);
初期ドラフトの3.8.6に詳細が記載されています。
- Criteriaを用いたバルクの更新・削除
CriteriaUpdate、
CriteriaDelete
、CommonAbstractQuery
インターフェースが追加され、AbstractQuery
インターフェースがリファクタリングされました。
仕様の6.5.15からCriteriaUpdate
のサンプルを引用します。
CriteriaUpdate<Customer> q = cb.createCriteriaUpdate(Customer.class);
Root<Customer> c = q.from(Customer.class);
q.set(c.get(Customer_.status), "outstanding")
.where(cb.lt(c.get(Customer_.balance), 10000));
これはJPQLの以下のコードと同義です。
UPDATE Customer c
SET c.status = 'outstanding'
WHERE c.balance < 10000
このクエリは以下のように実行できます。
@PersistenceContext EntityManager em;
Query query = em.createQuery(q);
query.executeUpdate();
初期ドラフトの6.5.15からCriteriaDelete
のサンプルを引用します。
CriteriaDelete<Customer> q = cb.createCriteriaDelete(Customer.class);
Root<Customer> c = q.from(Customer.class);
q.where(cb.equal(c.get(Customer_.status), "inactive"),
cb.isEmpty(c.get(Customer_.orders)));
これは以下のJPQLと同義です。
DELETE FROM Customer c
WHERE c.status = 'inactive'
AND c.orders IS EMPTY
このクエリは、前のサンプルと同様に、次のように実行できます。
@PersistenceContext EntityManager em;
Query query = em.createQuery(q);
query.executeUpdate();
- 新しい予約語
Java Persistence query languageの予約語(FUNCTION
,ON
,TREAT
)が追加されました。 - FUNCTIONを用いた事前定義済み関数、およびユーザー定義関数
JPQLではSELECT, WHERE or HAVING句で使うクエリの組み込み関数(CONCAT、SUBSTRING、TRIM、LENGTH、ABS、SQRTやCURRENT_DATE)を提供しています。. 仕様の4.6.17.3で、FUNCTION演算子を用いた事前定義済みデータベース関数やユーザー定義関数の呼び出し方を定義しています。演算子FUNCTION
を使って定義済みデータベース関数やユーザー定義関数を実行します。以下はサンプルです。
SELECT c
FROM Customer c
WHERE FUNCTION(‘hasGoodCredit’, c.balance, c.creditLimit)
- TREATを用いたダウンキャスト
FROM句やWHERE句中のパス表現でダウンキャストをサポートするためのTREAT
をサポートしています。演算子TREATを使うと、サブクラス固有の状態にアクセスすることができます。仕様の4.4.9に例があります。
SELECT b.name, b.ISBN
FROM Order o JOIN TREAT(o.product AS Book) b
この例では、Order
とProduct
を結合していますが、name
とISBN
は、Product
クラスのサブクラスであるBook
クラスの属性です。別の例を見てみましょう。
SELECT e FROM Employee e
WHERE TREAT(e AS Exempt).vacationDays > 10
OR TREAT(e AS Contractor).hours > 100
vacationDays
Exempt
クラスのemployeesのための属性であり、hours
はContractor
クラスの属性です。
- ONを用いた結合条件
SQLにおけるON句は表の関係を指定するために使用します。取り上げる行の条件を指定するWHERE句とは異なります。仕様の4.4.5.2のサンプルJPQLを見てみましょう。
SELECT s.name, COUNT(p)
FROM Suppliers s LEFT JOIN s.products p
ON p.status = 'inStock'
GROUP BY s.name
SQLにマッピングすると、こうなります。
SELECT s.name, COUNT(p.id)
FROM Suppliers s LEFT JOIN Products p
ON s.id = p.supplierId AND p.status = 'inStock'
GROUP BY s.name
LEFT JOINのためにs.id = p.supplierId
という条件を作成しています。 JPQLのON句があるために、追加のJOIN条件であるp.status = 'inStock'
もまた、先ほどの生成されたSQLに追加されています。このクエリの結果には、全てのサプライヤ(NULL値を含む)が含まれます。これは以下のクエリとは異なるものです。
SELECT s.name, COUNT(p)
FROM Suppliers s LEFT JOIN s.products p
WHERE p.status = 'inStock'
GROUP BY s.name
このクエリの結果には在庫がないサプライヤは含まれません。
ON句をサポートするFetch
、Join
、CollectionJoin
、SetJoin
、ListJoin
、MapJoin
のインターフェースにもメソッドが追加されています。
- CDIを用いるエンティティリスナー
エンティティリスナーを使うと、非永続リスナクラスの横断的なライフサイクルイベントを処理できます。JPA 2.1では、エンティティリスナーはCDIを通してのdependency injection(依存性の注入)をサポートしています。通常のライフサイクルコールバックメソッドの@PrePersist
、@PostPersist
、@PreUpdate
、@PreRemove
をエンティティ向けに利用できます。自身のライフサイクルのために@PostConstruct
や@PreDestroy
を用いてエンティティリスナーをアノテートすることができます。 初期ドラフトの3.5.1に詳細が記載されています。
jsr338-expertsのエイリアスやjpa-specのユーザーメーリングリストもご覧下さい。
[jsr338-experts] injection into entity listeners (Expert Group Mailing List)
http://java.net/projects/jpa-spec/lists/jsr338-experts/archive/2011-07/message/12
[jpa-spec users] Integration with CDI (Users Mailing List)
http://java.net/projects/jpa-spec/lists/users/archive/2011-07/message/1
- 永続コンテキストの同期
JPA 2では、永続コンテキストを基礎となるリソースマネージャと同期します。永続コンテキストになされた任意の更新は、リソースマネージャに伝えられます。JPA 2.1では、非同期永続コンテキストのコンセプトを導入しています。コンテナで管理されている非同期永続コンテキストを以下のように作成することができます。
@PersistenceContext(synchronization=SynchronizationType.UNSYNCHRONIZED) EntityManager em;
初期ドラフトの7.6.1に詳細があります。
- テキストおよびjavadocsでいくつか説明があります。
リファレンスの最終版はこちらです。
- JPA 2.1 Specification
http://jcp.org/en/jsr/detail?id=338 - Javadocs
http://java.net/projects/jpa-spec/downloads/download/JPA21Javadocs.zip
- EclipseLink/Development/JPA 2.1
http://wiki.eclipse.org/EclipseLink/Development/JPA_2.1
原文はこちら。
http://blogs.oracle.com/arungupta/entry/jpa_2_1_early_draft
0 件のコメント:
コメントを投稿