前提

こんな感じのOneToMany/ManyToOneなエンティティがあったとします。
子エンティティ「STREET」は、ひとつの親エンティティ「CITY」を持ちます。


+-------+ (1)   (n) +--------+
| CITY  |-----------| STREET |
+-------+           +--------+

プログラムはこんな感じ(いろいろ略しています)。

City.java

@Entity
class City {
  @OneToMany(mappedBy="city")
  private List<Street> streetList;
}

Street.java

@Entity
class Street {
  @ManyToOne
  private City city;

  public City getCity() {
    return city;
  }
}

問題

子エンティティ「STREET」を取得し、lambdaの中で親エンティティ「CITY」を取得しようとしても、SQLは実行されず取得できません。

Test.java

class Test {
  @PersistenceContext
  private EntityManager em;

  public void test {
    em.createQuery("SELECT s FROM Street s", Street.class)
      .getResultList()
      .stream()
      .forEach(x -> System.out.println(x.getCity().toString())); // ← ダメ
  }

原因

EclipsseLink 2.5.2のバグらしいです。2.6で直っています。

http://stackoverflow.com/questions/33151787/java-stream-with-jpa-one-to-manylazy-relation-not-working

つまりGlassfish 4.1はダメー :scream:

回避策

その1 @JoinFetchをつける

子エンティティに@JoinFetchをつけて、あらかじめ親エンティティも取得します。

Street.java

@Entity
class Street {
  @ManyToOne
  @JoinFetch             // ←追加
  private City city;

  public City getCity() {
    return city;
  }
}

その2 lambdaを使わない

どうもEclipseLinkとlambdaは相性悪いですね。。。


2015.10.28 追記
文中しっかりスペルやら間違えていました。
× lamda
○ lambda
× Eclipse 2.5.2
○ EclipseLink 2.5.2

@laughter さん、 @tag1216 さん、編集リクエストありがとうございました。
@deaf_tadashi さんコメントありがとうございました。