EclipseLinkでJPA
EclipseLinkを利用し、JPAでデータベース更新をしようと考えた。
サンプルを作成し、動かしてみたが下記のような課題が検出された。
実装について
- データ登録(INSERT)
事前に作成しておいたEntityクラスのインスタンスを作成し、そのプロパティをセット→EntityManager.persist(entity)で
レコードの登録ができる。お手軽。
EntityTransaction.commit()を実行しないとデータ更新はされない。
- データ更新(UPDATE)
更新対象レコードのEntityをEntitiManager.find(Entity.class, pk)で取得し、取得できたEntityのプロパティを更新するだけで、
レコードの更新ができる。お手軽。
更新はEntityManager.persistする必要もない。
EntityTransaction.commit()を実行すればよい。
登録のアクションが必要ないのは不安に思われることもあるかもしれないが、
エラー時はEntityManager.rollback()すれば更新されないので、更新忘れがなくて良い仕様だと思う。
- データ削除(DELETE)
これもとても簡単。EntityManager.find()で取得したentityをEntityManager.remove(entity)するだけ。
- データ取得(SELECT)
キーで取得するのは簡単。EntityManager.find(Entity.class, pk)で取得できる。簡単。
リストで取るときは、多少癖がある。
また、いくつか異なるアクセス方法がある。
1.SQLを使う方法
2.JPQLを使う方法
3.CriteriaQueryを使う方法
1.はコンパイラ警告が出るので使わないほうが良いかと思う。(SuppressWarningsして使ってもいいけど)
2.の方法がとっつきやすい気がする。
3.CriteriaQuery、Root、などなど、よくわからないクラスを使う。サンプルを見ながらでも、どのクラスがどの役割なのかわかりにくい。
- Entity作成にあたって
Entityクラスを生成するのは結構面倒。
特に複合主キーの場合。キーのみをクラス(内部クラスでも可)として定義する必要がある。
JPAでは主キーを単一項目にすることが推奨されているらしい。
すでに複合キーのテーブルで検証したため、なかなか面倒だった。
CREATE TABLE T01 (
C01 CHAR(10) NOT NULL,
C02 CHAR(2) NOT NULL,
C03 VARCHAR2(100),
C04 VARCHAR2(100),
PRIMARY KEY (C01, C02)
)
上記のテーブルの場合、Entityは下記のようになる。
package entity;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
@Entity(name = "T01")
public class T01 {
@EmbeddedId
public PK pk;
@Embeddable
public static class PK {
@Column(name = "C01", nullable = false)
public String c01;
@Column(name = "C02", nullable = false)
public String c02;
public boolean equals(Object obj) {
PK tgt = (PK) obj;
return c01.equals(tgt.c01) && c02.equals(tgt.c02);
}
public int hashCode() {
return (c01 + c02).hashCode();
}
}
@Column(name = "C03", nullable = false)
public String c03;
@Column(name = "C04", nullable = false)
public String c04;
}
実行環境について
- EclipseLinkのバージョン
最新バージョンは2.7.0。これはjava8以降で動作する。
あえてjava7で利用したい場合は、2.6.4を利用する。
- Entityをjarファイルにまとめている場合
Entityクラスがjarファイルに入っている場合は、persistence.xmlに設定が必要。
classファイルのまま、クラスパスにおいてある場合は、@Entityのクラスを自動的に読んでくれる。
jarファイルに入っている場合は、
1.Entityクラスを
これはすべてのクラスをここに書かなくてはならないので、追加・変更時のメンテンナンスがなかなか大変。
2.Entityクラスが入っているjarファイルを
これであれば、jarファイル内の@EntityのクラスをEntityとして自動的に読んでくれる。
ただし、jarファイルを参照するパスが独特なので注意する必要がある。
絶対パスで指定する場合は、あまり気にしなくてよいが、通常はディレクトリ構成に左右されないように相対パスで指定すると思う。
カレントディレクトリはクラスパスで最初に見つかったMETA-INF/persistence.xmlが存在するディレクトリとなる。
たとえば、top_dir/conf_dir/META-INF/persistence.xmlの様にpersistence.xmlが存在する場合、top_dir/conf_dirがカレントディレクトリとなる。
したがって、top_dir/libにエンティティが収められたjarが保存されていた場合、persistence.xmlには下記のように書く。
ここに宣言されたjarファイルはクラスパスを追って読むわけではないので注意が必要。
- eclipseの良く使うショートカットキー
- eclipseデフォルトの文字コード
- itext5でPDFを暗号化する
- Java DateFormat
- Java8で指定回数繰り返し
- Java9でJAXB
- JavaでZip圧縮
- javaでイメージフォーマット変換
- javaでダミー画像作成
- javaでファイルの更新日時を変更する
コメントを残す