JPA/Hibernate preUpdate不更新父对象

lha*_*iak 4 java hibernate jpa-2.0

在我的应用中,我定义了以下类:

@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;
Run Code Online (Sandbox Code Playgroud)
@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());
    }
Run Code Online (Sandbox Code Playgroud)

如果我尝试向论坛实体添加新帖子,lastActivity则通过@PrePersist回调在数据库中正确更新字段.但是,如果我尝试使用以下代码更新post实体:

  entityManager.getTransaction().begin();
  Post post = entityManager.find(Post.class, "postId");
  post.setContent("New post text");
  entityManager.merge(post);
  entityManager.getTransaction().commit();
Run Code Online (Sandbox Code Playgroud)

仅更新发布数据且lastActivity字段值不会更改.在我看来,@PreUpdate方法应该做的伎俩和更新论坛实体.这是一个错误还是我错过了什么?

Mik*_*unu 8

这不是错误,即使通过快速尝试,这对我的预期方式起作用.负面消息是,由于以下原因,它不能保证有效:

从JPA 2.0规范中的第93页开始:

通常,可移植应用程序的生命周期方法不应调用EntityManager或Query操作,访问其他实体实例或修改同一持久化上下文中的关系.[43] 生命周期回调方法可以修改调用它的实体的非关系状态.

和第95页:

依赖于实现,是否在将生命周期事件级联到相关实体之前或之后调用回调方法.应用程序不应该依赖于此顺序.