JPA / Hibernate preUpdate does not update the parent

In my application, I defined the 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 to add new posts to the forum entity, the lastActivity field will be correctly updated in the database using the @PrePersist callback. But if I try to update the mail entity using the 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 is updated, and the value of the lastActivity field lastActivity not changed. In my opinion, the @PreUpdate method should do the trick and update the Forum object. Is this a mistake or am I missing something?

+4
source share
2 answers

This is not a mistake, even with a quick try it worked for me the way you expected. The negative news is that it is not guaranteed to work, because:

From page 93 in the JPA 2.0 specification:

In general, a portable application’s lifecycle method should not invoke EntityManager or Query operations, access instances of another object, or modify relationships within the same context. [43] The lifecycle callback method can change the relationship state of the object on which it is called.

And page 95:

The implementation depends on whether the callback methods are called before or after the cascading of life cycle events to those associated with them. Applications should not depend on this order.

+8
source

post.merge() is useless here. post explicitly attached to the session.

Make sure the content attribute is mapped to the column; if it is not, Hibernate cannot tell if the object is dirty and therefore discard the changes to the database.

0
source

All Articles