使用spring-data-jpa 2.0.8.RELEASE
我有一个@OneToMany
相关实体对。假设King
和Peasant
。我希望有一个逻辑,当更新农民时,这也会手动更新国王@LastModifiedDate
的值。我做这样的事;
@PreUpdate
@PreRemove
@PrePersist
void updateParents() {
Date now = new Date();
BaseEntity container = getParent();
while (Objects.nonNull(container)) {
container.setUpdateDateTime(now);
container = container.getParent();
}
}
,并且效果很好,这意味着它确实将所有父母更新为国王(表结构确实混乱,从国王到最低农奴的深度为5),我遇到的问题是,对父母的修改不是坚持不懈。我有以下服务;
@Transactional
public void update(String kingId, String peasantSeqNo) {
Peasant peasant = peasantRepository.getPeasant(kingId, peasantSeqNo);
peasant.setNobility(false);
peasantRepository.save(peasant);
}
在上面的代码中,触发了@PreUpdate
注释的updateParents()
方法,并且国王的更新时间戳也被更新,即使在事务结束之后,该更改也不会持久。我可以使用显式的kingRepository.flush()
来触发这种持久性,但是我希望可以自动完成,只需修改父级即可。
国王农民之间的联系如下;
@JsonManagedReference
@OneToMany(mappedBy = "parent", cascade = REMOVE)
private List<Peasant> peasantry;
和
@JsonBackReference
@MapsId("kingId")
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "ID_KING", referencedColumnName = "ID_KING", nullable = false)
private King parent;
这在某种程度上影响了我对JPA的使用,但是找不到确切的原因和解决方案,您能对此提供任何意见吗?
答案 0 :(得分:1)
您遇到了JPA(实施)的限制。
事件触发后,JPA实现已经决定了它将保留的实体,因此您的更改不会被提取。
此行为实际上定义为未在JPA规范中定义:
通常,可移植应用程序的生命周期方法不应调用EntityManger或查询操作,访问其他实体实例或在同一持久性上下文中修改关系[46]。[47]生命周期回调方法可能会修改在其上调用它的实体的非关系状态。
[46]请注意,此警告还适用于可能注入到实体侦听器中的对象的操作。
[47]此类操作的语义可能会在此规范的将来版本中进行标准化。
因此,您需要将此行为从JPA监听器转移到业务逻辑中。