web-dev-qa-db-ja.com

JPAの名前付きクエリとCriteriaAPI?

Criteria APINamedQueryの間の決定のためのヒューリスティック/ベストプラクティス/ルールセットはありますか?

これまでの私の考え:
名前付きクエリは一般的に読みやすくなっています。基準クエリはより柔軟です。
両方ともプリコンパイルされています。私は、名前付きクエリをできるだけ長く使用してから、基準に変更することに依存する傾向があります。

しかし、基準APIを使用してクエリを「柔軟化」したいという衝動は、最適ではない設計(つまり、関心の分離)のヒントになるのではないでしょうか。

ありがとうございました

28
kostja

名前付きクエリの方が最適です(一度解析/準備されます)。基準クエリは動的です(EclipseLinkなどの一部のJPAプロバイダーは基準準備キャッシュを維持していますが、プリコンパイルされていません)。

動的クエリにのみ基準を使用します。

34
James

基準クエリは、たとえば、可変および複数の検索基準に基づいてクエリを動的に生成する必要がある場合に適しています。

静的クエリの場合、JPQLの方がはるかに読みやすく、基準クエリよりもJPQLを使用する方が好きです。安全性がいくらか失われる可能性がありますが、単体テストを実行すると自信が増します。

10
JB Nizet

もう1つの視点は、基準クエリはそれほど読みやすくはありませんが、型セーフであるため、コンパイル時の型チェックを提供するということです。多くのエンティティと多くのクエリがあるプロジェクトでデータベースを変更する場合、変更によってどのクエリが失敗したかをコンパイル時に確認すると非常に役立ちます。

一方で、それがJPQLのシンプルさよりも有益かどうかはわかりません

4

私は実際にHibernate(4.3.0-SNAPSHOT)ソースとEclipseLink(2.5.0-SNAPSHOT)ソースを調べ、それぞれのJPA実装を調べました。

EclipseLinkは、あなたが説明した方法では明らかにスレッドセーフではありません。具体的には、結合を繰り返し再計算しようとします。

Hibernateの実装は、スレッドセーフに見えます。 100%確信はありませんが、確かにそうです。これは明記されていないので、将来的には真実であるとは限りません。

しかし、私はあなたに警告します、私はあなたが多くを得るつもりはないと思います。私が見ているところによると、クエリのコンパイルの多くは実際には「createQuery」フェーズで行われるため、結果をキャッシュすることすらできません。

2
Yinzara

JPAは、@ NamedQueryおよび@NamedQueriesアノテーションを使用して、静的クエリを名前付きクエリとして構築する方法も提供します。 JPAでは、可能な場合は動的クエリよりも名前付きクエリを優先することをお勧めします。から http://www.objectdb.com/Java/jpa/query/api