2017年度 Java 永続化フレームワークについての考察(7) EclipseLink

#前ポスト
- [2017年度 Java 永続化フレームワークについての考察(1)](http://qiita.com/shiroma_yuki/items/8d434862bba072bff264)
- [2017年度 Java 永続化フレームワークについての考察(2) Doma2](http://qiita.com/shiroma_yuki/items/d0e3b319626f4278fc6f)
- [2017年度 Java 永続化フレームワークについての推測(3) Reladomo](https://qiita.com/shiroma_yuki/items/1e3d83202afa6cf5dbef)
- [2017年度 Java 永続化フレームワークについての考察(4) jOOQ](https://qiita.com/shiroma_yuki/items/1f64cac07afc745579a5)
- [2017年度 Java 永続化フレームワークについての考察(5) Iciql](https://qiita.com/shiroma_yuki/items/42e2cf97076c964e8629)
- [2017年度 Java 永続化フレームワークについての考察(6) Ebean](https://qiita.com/shiroma_yuki/items/283c89ad13f90e25c0d5)

#前置き
隙間時間を利用して書いているので精度の甘い箇所があれば、ご指摘いただけると幸いです。
まずEOLであるものは除外。
有償の機能については検討対象に含むが、実際に使用はしません、懐の問題で。
「まぁ、たぶん明記されてなくてもPostgreならいけるだろ」ぐらいの間抜けな理由で使用DBはPostgreに固定。

#環境
- PostgreSQL 9.6.3
- [Eclipse Link 2.7.0](http://www.eclipse.org/eclipselink/)
- [org.eclipse.persistence javax.persistence 2.1.1](https://mvnrepository.com/artifact/org.eclipse.persistence/javax.persistence/2.1.1)
- Java 64bit 8u144

#テーブル構成
![employeeテーブルからpostテーブルにID紐づけ](https://qiita-image-store.s3.amazonaws.com/0/48666/ec265f75-ad54-4f56-a5f8-2b460723047a.png)


#対応範囲
|ORM|Transaction|Data Model|DSL|
|:-:|:---------:|:--------:|:-:|
|○|○|×|○|
○:対応
×:非対応

#所感
- エンティティの自動生成がないのツラい
- コンテナなし環境で使うとEntityManagerの仕様が迂遠に思えますね
- persistence.xmlとか使うまで忘れてた
- JPA2.0で注釈処理を使用してメタモデルを生成するようになっている、型セーフ、カラム名変更耐性などがパワーアップ
    - ……メタモデル、他のORMライブラリに比べるとダサくない？
- EclipseLink2.7.0のjavax.persistenceが署名違いでエラー、なんでや、結局javax.persistence2.1.1を入れる謎回避

#サンプル
##単テーブル検索
###全件検索
```Main.java
CriteriaQuery<Employee> query = em.getCriteriaBuilder().createQuery(Employee.class);
em.createQuery(query).getResultStream().forEach(e -> {
    System.out.format("%1s: %2s, %3s, %4s\n", e.id, e.first_name, e.middle_name, e.last_name);
});
```

###主キー検索
```Main.java
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Employee> query = builder.createQuery(Employee.class);
Root<Employee> root = query.from(Employee.class);
em.createQuery(query.select(root).where(builder.equal(root.get(Employee_.id), 1L)))
        .getResultStream()
        .forEach(e -> {
    System.out.format("%1s: %2s, %3s, %4s\n", e.id, e.first_name, e.middle_name, e.last_name);
});
```

##テーブル結合
```Main.java
em.createQuery(query.select(root).where(builder.equal(root.get(Employee_.id), 1L)))
        .getResultStream()
        .forEach(e -> {
    System.out.format("%1s: %2s, %3s, %4s\n", e.id, e.first_name, e.middle_name, e.last_name);
    e.posts.stream().forEach(p -> {
        System.out.format("\t%1s: %2s, %3s\n", p.id, p.employee_id, p.name);
    });
});
```
```Employee.java
@Entity
@Table(name="employee")
public class Employee {
    @Id
    public long id;
    public String first_name;
    public String middle_name;
    public String last_name;

    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumn(name = "employee_id", table = "post")
    public List<Post> posts;
}
```
```Post.java
@Entity
@Table(name="post")
public class Post {
    @Id
    public long id;
    public long employee_id;
    public String name;
}
```

#要点
- JPA参照実装なのでJPAです

#ハマったポイント
- 普通にEclipseLink2.7.0を使ってビルドすると「javax.persistenceの署名が異なる」とか怒られる
    - [Bug 525457](https://bugs.eclipse.org/bugs/show_bug.cgi?id=525457) マジかよ承太郎

#後ポスト
まだない。

#参考記事
- [JPAマッピングカタログ](https://qiita.com/opengl-8080/items/5190ee953cfbab5ce3e9)
- [JavaEE使い方メモ（JPA その4 - クライテリアAPI）](https://qiita.com/opengl-8080/items/6e3e03e4c90cd3d5e211)