初めてのJPA--シンプルで使いやすい、Java EEのデータ永続化機能の基本を学ぶ

WebLogic Channel編集部
2015-07-08 17:00:00
  • このエントリーをはてなブックマークに追加

Java EEアプリケーションにおけるデータベース操作を、よりシンプルで簡単にするためのデータ永続化機能が「JPA(Java Persistence API)」だ。同APIのキホンを、書籍「わかりやすいJava」シリーズでおなじみの川場隆氏が解説する。

 Java EE 6や同7など最新のJava EEを使用したアプリケーション開発に初めて取り組む方にとって課題の1つとなるのは、Java EE特有のデータ永続化機構である「JPA(Java Persistence API)」の習得であろう。入門者向けのJava解説書として定評のある「わかりやすいJava」シリーズで知られる川場隆氏(活水女子大学 教授)の解説により、JPAの基本を学んでいただきたい。

※本記事は、日本オラクルが2015年4月に開催した「Java Day Tokyo 2015」における川場隆氏のセッション「やさしく理解するはじめてのJPA」の内容を基に構成しています。

JPAとは何か?


活水女子大学 教授の川場隆氏

 この記事では、JPAを初めて学ぶ方に対して、同APIを使う際に必要となる基本的な事項を解説します。

 まずは「JPAとは何なのか」ということから始めましょう。端的に言えば、JPAとはJavaの世界とリレーショナル・データベース(RDB)の世界を直接的に結ぶための仕組みです。「JavaのオブジェクトとRDB(レコード、テーブル)との間で自動変換を行う仕組み」がJPAだと理解していただけばよいでしょう。

 下図に示すように、Javaの世界では「参照」によってオブジェクト間を結び付け、RDBの世界では「キー・カラム」によってデータベース・テーブルの間を結び付けています。


※クリックすると拡大画像が見られます

 この「参照」と「キー・カラム」による関連付けの間を相互変換することで、JavaオブジェクトとRDBの間の関連付けを行うのがJPAの役割なのです。

 JPAの主な特徴を列挙すると、次のようになります。

  • Javaオブジェクトとデータベース・テーブルとの間の変換指定(マッピング指定)をアノテーションだけで行える
  • Javaオブジェクトを、そのまま読み書き/削除/検索することができる
  • オブジェクト指向の問い合わせ言語(JPQL:Java Persistence Query Language)を利用できる
  • JPQLと同等のAPIも使うことができる

 JPAの仕組みは非常にシンプルであり、次の3つの要素から成ります。

  • エンティティ:データベースに保管するオブジェクト。つまり、データベース・レコードに相当するオブジェクト
  • エンティティ・マネジャー(EntityManager):エンティティを管理するオブジェクト
  • 永続性コンテキスト:EntityManagerの配下にあり、エンティティの状態を表すオブジェクト

 この3つの要素の中でも、中心的な役割を担うのがEntityManagerです。EntityManagerがエンティティを受け取り、さまざまなデータベース処理を一括して実行するのです。


※クリックすると拡大画像が見られます

エンティティの作り方

 JPAでは、エンティティを表すクラス(エンティティ・クラス)の作成も簡単に行えます。普通のJavaクラスを作り、それに@Entityというアノテーションを書くだけでよいのです。これだけで、作成したクラスを「データベースに書き込む1件のレコード(つまり、エンティティ)」として定義することができます。

【リスト1:エンティティ・クラスの例】
import java.io.Serializable; import javax.persistence.*; import javax.validation.constraints.NotNull; @Entity public class Employee implements Serializable { @Id @NotNull // Null禁止。ビーン・バリデーションも指定できる private Integer number; // 社員番号 private String name; // 氏名 private String mail; // メール public Employee(){} // 実用上はインスタンスを生成するためのコンストラクタも作っておく public Employee(Integer number, String name, String mail){ …略… } // setter/getterメソッド。NetBeansなどのIDEを使うと自動生成できる }

 このほか、リスト1からもわかるように、エンティティ・クラスの作成に当たっては次のような簡単な決まり事があります。

  • 主キーの項目に@Idを付ける
  • publicで引数のないコンストラクタを持たせる
  • 必ずカプセル化を行う(setter/getterメソッドを用意する)
  • クラスやフィールドにfinal修飾子を付ける

 ちなみに、Java対応統合開発環境の「NetBeans」を使うと、setter/getterメソッドのコードが自動的に生成されるので便利です。

EntityManagerの基本メソッド

 EntityManagerは、パッケージjavax.persistenceのインタフェースであり、主なメソッドとして次が用意されています。

【表1:インタフェースEntityManagerで宣言されているメソッド】

メソッド 機能
void persist(Object e) エンティティeをデータベースに新規登録する
E merge(E e) データベース中のエンティティを引数に指定されたエンティティeで更新する
void remove(Object e) エンティティeを(データベースから)削除する
E find(E.class, Object key) key(主キー)で検索して見つけたエンティティを返す
E getReference(E.class, Object key) findと同様だが、遅延フェッチを行う
void refresh(Object e) 永続性コンテキストにあるエンティティeを、データベースから取得した値で更新する
void clear() 永続性コンテキストをクリアし、エンティティを永続性コンテキストから分離する
void flush() 永続性コンテキストにあるエンティティを即時にデータベースと同期する
void detach(Object e) 引数のエンティティを、永続性コンテキストから分離する
boolean contains(Object e) 引数に指定されたエンティティが永続性コンテキストの中にあるかどうかを調べる

 最初は、表中の「persist(新規登録)」、「merge(更新)」、「remove(削除)」、「find(検索)」という4つのメソッドを覚えておけばよいでしょう。

 それでは、これらのメソッドはどこに書くのでしょうか。答えは簡単、EJBクラスに定義すればよいのです。


※クリックすると拡大画像が見られます

 Java EEでは、普通のクラスに@statelessというアノテーションを付けると、そのクラスがEJBコンテナの管理対象となり、データベースとのトランザクション制御などが自動的に行われます。なお、上の図中で下線を引いたメソッドpersist、mergeの引数に指定している「obj」がエンティティ・オブジェクトです。

 また、EntityManagerオブジェクトは、DI(Dependency Injection:依存性の注入)によって取得します。つまり、@PersistenceContextというアノテーションにより、EJBクラスの変数に対してEntityManagerオブジェクトへの参照を注入できるわけです。後は永続性コンテキストに対し、前掲のEntityManagerのメソッドによって実行したいエンティティの操作を指定します。

 このように、EntityManagerの使い方はとても簡単ですが、エンティティごとにEJBクラスが必要となるため、複数のエンティティを使う場合には作成に手間がかかります。これを避けるには、下図の要領でどのような型のエンティティでも処理することのできる"総称型のスーパークラス"を使うとよいでしょう。


※クリックすると拡大画像が見られます

※クリックすると拡大画像が見られます

 これにより、エンティティごとのEJBクラスのコーディングを次のように簡素化することができます。


※クリックすると拡大画像が見られます

 エンティティごとに、上図のように6行のコードから成るクラス、つまりCreate(生成)、Read(読み取り)、Update(更新)、Delete(削除)のCRUD処理を行うEJBクラスを作ればよいわけです。

 ただし、検索系のメソッドでは、エンティティの型情報が必要となるので、総称型スーパークラスのコンストラクタの引数で型情報を取得できるようにしておきます。


※クリックすると拡大画像が見られます