Javaでplay 2.0.4を使用しています。play が提供するメモリ内データベースから値を保存して取得しようとしています (Ebean は基礎となる JPA 実装です)。サンプルコードは次のとおりです。
@NoobDisclaimer ("I'm fairly new to Play and JPA")
@Entity
public class User extends Model {
@Id
public Long id;
public String name;
// Does not fetch eagerly.
@ManyToOne(fetch=FetchType.EAGER)
private Role role; // Role extends Model { has id and name}
public static Finder<Long, User> find = new Finder<Long, User>(Long.class, User.class);
public static List<User> all() {
List<User> allUsers = find.all();
for (User u : allUsers) {
System.out.println("User:" + u.id + "|" + u.name); // SOP1
// System.out.println("Assoc Role:" + u.role.name); //SOP2
}
return allUsers;
}
public static void create(User user) {
user.save();
}
}
index.scala.html では、@(users: List[User]、userForm: Form[User])
<h2>@users.size() user(s) found!</h2>
<ul>
@for(usr <- users) {
<li>Name: @usr.name</li> <!-- Displayed -->
<li>Role: @usr.role.name</li> <!-- Displays blank value -->
}
</ul>
問題は、コントローラーで User.all() を実行してそれをビューに送信すると、user.role がロードされない、つまり @usr.role.name が空白になることです。例外はありません。SQL デバッグをオンに設定し、Role テーブルへの外部キーが User テーブルに保存されていることを確認しました。User.all() メソッド (SOP2 を参照) でロール名を出力すると、クエリが起動され、ロール名が出力されます。ビューにも表示されます。
デフォルトでは、ロールは遅延ロードされ、テンプレートで PersistenceContext を使用してユーザーに関連付けられたロールをロードできないことを理解しています。しかし、熱心なフェッチは、オブジェクトに関連付けられたすべてのエンティティを取得するべきではありませんか? 私は Play と JPA にかなり慣れていないので、何かをロードするときに関連する各エンティティを経由せずにこれを機能させる方法を理解できません。足りないものはありますか?
関連するメモとして、遅延フェッチを使用する必要がある場合、ユーザーをフェッチするときにビューで user.role を使用できるようにするにはどうすればよいですか?