When is @OneToMany list populated in Play framework?
The Play framework's Yet Another Blog Engine example has a Post class with children Comments:
// Post.java
// ... other fields, etc.
@OneToMany(mappedBy="post", cascade=CascadeType.ALL)
public List<Comment> comments;
// ...
When data is populated by the .yml, everything seems to work fine:
// BasicTest.java
@Test
public void fullTest() {
Fixtures.load("data.yml");
// ...
// Find the most recent post
Post frontPost = Post.find("order by postedAt desc").first();
assertNotNull(frontPost);
// ...
// Check that this post has two comments
assertEquals(2, frontPost.comments.size()); // succeeds
}
But when I manually save a Post and some Comments to the database, the frontPost.comments field is empty:
@Test
public void myFullTest() {
// Fixtures.load("data.yml");
User u = new User("bob@gmail.com", "secret", "Bob").save();
Post p = new Post(u, "About the model layer", "The model has a central position in a Play! application. It is the ...").save();
Comment c1 = new Comment(p, "Guest", "You are right !").save();
Comment c2 = new Comment(p, "Mike", "I knew that ...").save();
// Find the most recent post
Post frontPost = Post.find("order by postedAt desc").first();
// This assertion fails as frontPost.comments is empty:
// "Failure, expected:<2> but was <0>"
assertEquals(2, frontPost.comments.size());
}
Why does this happen, and how can I make JPA开发者_如何学编程 populate the Post.comments field when saving the classes one by one?
Thanks all!
Update: the solution was to call JPA.em().clear() before the find(....) call.
You want to be calling em.refresh(p) instead of clearing the whole persistence context and detaching all your other entities.
This does however involve querying the db, so Play implement a helper method later on in the tutorial which will update the in-memory entity after persisting the new comment to save you a trip.
When using bidirectional relationships in JPA, maintaining consistency between both sides of the relationship for in-memory objects is up to you.
I'm not sure how Play Framework implements find()
, but if frontPost
is the same instance as p
(i.e. not a fresh instance constructed from database data), it's comments
collection is certainly empty.
精彩评论