I'm using play 2.0.4 with Java. I'm trying to save and retrieve a value from the in-memory db that play provides (Ebean is the underlying JPA implementation). Here's some sample code:
@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(); }
}
In 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>
The problem is that when I do a User.all() in the controller and send it to the view, user.role is not loaded, i.e., @usr.role.name is blank. There is no exception. I have set SQL debugging on and I have verified that a foreign key to the Role table is saved in the User table. When I print the role name in the User.all() method (see SOP2), a query is fired and the role name is printed. It also shows up on the view.
I understand that, by default, the role would be lazily loaded and that the PersistenceContext would not be available in the template to load the role associated with the user. However, shouldn't an eager fetch get me all assocaited entites for an object? I'm fairly new to Play and JPA and I can't figure out how to get this to work without going through each associated entity when I load something. Is there something I'm missing?
On a related note, if I had to use lazy fetch, how do I ensure that the user.role is available to the view when I fetch a user?