In my application I defined following classes:
@Entity
@Table(name = "forums")
public class Forum {
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
private String id;
private String name;
private Date lastActivity;
@OneToMany(mappedBy = "forum", cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE })
private List<Post> posts;
@Entity
@Table(name = "posts")
public class Post {
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
private String id;
private String username;
private String content;
private Date creationDate;
@ManyToOne(optional = false, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
private Forum forum;
public Post() {
creationDate = new Date();
}
@PrePersist
private void onPersist() {
System.out.println(getClass().getName() + ": onPersist");
if (creationDate == null) {
creationDate = new Date();
}
forum.setLastActivity(creationDate);
}
@PreUpdate
private void onUpdate() {
forum.setLastActivity(new Date());
}
If I try adding new posts to forum entity, lastActivity
field is correctly updated in database by @PrePersist
callback.
But if I try to update post entity using following code:
entityManager.getTransaction().begin();
Post post = entityManager.find(Post.class, "postId");
post.setContent("New post text");
entityManager.merge(post);
entityManager.getTransaction().commit();
only post data are updated and lastActivity
field value doesn't change. In my opinion @PreUpdate
method should do the trick and update Forum entity.
Is this a bug or am I missing something?
It is not bug, even that with a fast try this worked for me way you expected. Negative news is that it is not guaranteed to work, because of:
From page 93 in JPA 2.0 specification:
In general, the lifecycle method of a portable application should not invoke EntityManager or Query operations, access other entity instances, or modify relationships within the same persistence context.[43] A lifecycle callback method may modify the non-relationship state of the entity on which it is invoked.
And page 95:
It is implementation-dependent as to whether callback methods are invoked before or after the cascading of the lifecycle events to related entities. Applications should not depend on this ordering.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With