在我的应用程序中,我定义了以下类:
@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());
}
如果我尝试向论坛实体添加新帖子,lastActivity
字段会通过 @PrePersist
回调在数据库中正确更新。
但是,如果我尝试使用以下代码更新帖子实体:
entityManager.getTransaction().begin();
Post post = entityManager.find(Post.class, "postId");
post.setContent("New post text");
entityManager.merge(post);
entityManager.getTransaction().commit();
只更新发布数据,lastActivity
字段值不变。在我看来,@PreUpdate
方法应该可以解决问题并更新论坛实体。
这是错误还是我遗漏了什么?
最佳答案
这不是错误,即使通过快速尝试,这对我来说也符合您的预期。负面消息是它不能保证有效,因为:
从 JPA 2.0 规范的第 93 页开始:
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.
第 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.
关于java - JPA/Hibernate preUpdate 不更新父对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7753702/