JPAを深掘りする〜Criteria APIで型安全な検索を追求しよう!【基本編】


今回はJavaEEの中でも特に重要な「JPA(Java Persistence API)」を深掘りしてみます。基本編と応用編の2回に渡ってじっくりとJPAをご紹介します。

JPAとは

JPAは一言で言えば「高機能なDBアクセスフレームワーク」です。DBアクセスフレームワークは実に様々なものがありますが、JPAの特徴は

  • エンティティクラスへの操作を通してDB操作を実現する(DBの都合はプログラマから極力隠される)
  • 型安全を追求するための様々な機能を備える

が挙げられます。Javaの良さを引き出す工夫に満ちたフレームワークと言えるでしょう。

様々な機能を備えたJPAですが、本エントリでは、検索、中でもCriteria APIを使った型安全な検索を中心にご紹介します。コードをしっかり載せていきますので、Criteria APIのコンセプトを感じ取っていただけると思います。

なお、JPAを動作させる環境を構築する方法は「JavaEEだけでここまでできる!GlassFish+Eclipseで高速Webアプリ開発【環境構築編】」をご覧下さい。

準備1・メタモデルクラスを自動生成する設定

メタモデルクラスとは、エンティティクラスのプロパティに関する情報を表すクラスであり、型安全にJPAを使うためには欠かせないクラスです。

例えば次のようなエンティティクラスがあったとしましょう。

このエンティティクラスに対するメタモデルクラスは次のようになります。

メタモデルクラスはeclipseのような開発環境に自動で作ってもらうことができますので、有効にしておきましょう。

ecliseの場合の手順を紹介しておきます。プロジェクトのプロパティを開き、「プロジェクト・ファセット」から「Convert to faceted form…」をクリックします。

convert-to-faceted-form

 

プロジェクト・ファセットが有効になったので、JPAサポートを有効にします。

project-facets-jpa

ここで「 OK」を押していったんプロパティ画面を閉じます。

再びプロパティ画面を開くと「JPA」という設定項目が増えていますので、メタモデルクラスの自動生成を有効にします。

eclipse-jpa-metamodel

これで、エンティティクラスに変更が入る度にメタモデルクラスが自動生成されます。メタモデルクラスの名前はエンティティクラスの名前の後ろに _ を付けたものになります。

entity-metamodel

 

準備2・SQLをコンソールに出力する設定

JPAを使いこなすコツはJavaコードを中心に考えることですが、さすがにSQLが見えないと辛すぎます。せめてコンソールにSQLを出力するようにしておきましょう。JPAの設定ファイルであるpersistence.xmlにプロパティを追記します。

EclipseLinkの場合

OpenJPAの場合

APサーバにGlassFishを使っているのであれば、EclipseLinkの方を設定してください。

スキーマ定義をエンティティクラスで行う

JPAの良さを引き出すコツは、Javaコードを中心に考えることです。まずはスキーマ定義をエンティティクラスで行うようにしてみましょう。

ただ、実はJPAの仕様にはエンティティクラスからDDLを作る機能は含まれていません。JPAの実装であるEclipseLinkやOpenJPAの機能を使います。通常、persistence.xmlにプロパティを追記します。

EclipseLinkの場合

OpenJPAの場合

APサーバにGlassFishを使っているのであれば、EclipseLinkの方を設定してください。

Criteria APIによる検索

JPAの検索には、JPQLとCriteria APIの2つのやり方があります。JPQLは文字列でクエリを記述するため、コンパイル時に型チェックが全く働きません。

例えば以下のコードは実行時にClassCastExceptionがスローされてしまいます。

よく見ると、クエリ文字列がfrom Tagとなっています。結果のエンティティはUser型で受けていますから、型が異なっていおり、実行時にClassCastExceptionがスローされるのです。

しかしCriteria APIを使うと、このようなミスはコンパイル時に検出できるようになります。上のJPQLをCriteria APIで描き直してみましょう。

eclipseでこのコードを書くと、以下のようにコンパイルエラーとしてミスを教えてくれます。

jpa-criteria-error

 

このように、Criteria APIを使うとクエリのミスをコンパイル時にチェックできるようになります。これがCriteria APIの最大の利点です。

また、副次的な効果ですが変なクエリが書かれないようになります。実際の開発現場では、変態的なSQLが横行してチューンングの足枷になったり、特定のDB製品でしか実行できない書き方がされていたりと、SQL周りの問題が起きやすいです。しかしCriteria APIを使えばクエリの記述方法がある程度統一されるため、問題が起きにくく、またレビューしやすくなります。

Criteria APIによるクエリの基本形

Criteria APIはJPQLの構造をJavaクラスで表現したものと考えることができます。JPQLの構成要素の基本は次の3つです。

  1. from句:どのエンティティ(≒テーブル)からデータを取得するか
  2. where句:抽出条件
  3. select句:どのエンティティ、あるいはプロパティなどを取得するか

この3つを踏まえると、Criteria APIを使ったプログラムの基本形は次のようになります。

結果の型を指定できるのがとても強力です。例えば全件数を得るクエリは次のように書けます。


基本編はここまでです。次回の応用編では、Criteria APIの実戦的な機能をご紹介します。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">