JPA / Hibernate preUpdate不更新父对象
在我的应用程序中我定义了以下类:
@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 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()); }
如果我尝试向论坛实体添加新post,则可以通过@PrePersist
回调在数据库中正确更新lastActivity
字段。 但是,如果我尝试使用以下代码更新post实体:
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页开始:
通常,可移植应用程序的生命周期方法不应调用EntityManager或Query操作,访问其他实体实例或修改同一持久化上下文中的关系。[43] 生命周期回调方法可以修改调用它的实体的非关系状态。
和第95页:
它是依赖于实现的,是否在将生命周期事件级联到相关实体之前或之后调用回调方法。 应用程序不应该依赖于此顺序。
post.merge()
在这里没用。 post
已明确附在会议上。
确保你已经将content
属性映射到列,如果不是,Hibernate无法确定实体是否是脏的,因此将更改刷新到DB。
- 只读模式下不允许写操作 – 持久化时发出
- HIbernate映射exception:PropertyNotFoundException:找不到setter
- 使用注释的Hibernate Enum映射
- hibernate session.save()没有反映在数据库中
- 注入自动连接的依赖项失败; 嵌套exception是org.springframework.beans.factory.BeanCreationException:
- Spring JpaRepository – 分离和附加实体
- 如何解决Hibernateexception的原因“调用setter时发生了IllegalArgumentException”?
- 数据库表中的多语言字段
- 如何知道已分离的JPA实体是否已被保留?