我有一个像这样定义的OneToMany关系:
@Entity
Parent extends BaseEntity {
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE})
private List<Child> childList;
// ...
}
@Entity
Child extends BaseEntity {
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "PARENT_ID")
private Parent parent;
// ...
}
@Version注释在BaseEntity类中定义。实体转换为DTO并由客户更改。现在,当客户端更改其中一个子元素时,父元素及其子元素将转换回实体,并通过执行em.merge(父元素)完成合并,所有子元素的版本将增加1!我预计更改后的子项的版本只会增加。首先我认为是因为我的EntityCallbackListener拦截了与@PreUpdate的合并。但是如果我注释掉回调方法,其他子代的版本字段仍会增加。有没有人对这种行为有解释?
我正在使用OpenJPA 1.2.3。
好的,RTFM有时会帮助......: - /
增加所有孩子的版本是OpenJPA默认值:
此锁定管理器不执行任何独占锁定,而是执行 通过验证所有版本的版本来确保读取一致性 读取锁定实例在事务结束时保持不变。 此外,写锁定将强制增加到版本at 事务结束,即使对象不是这样 改性。这确保了读取与非阻塞行为的一致性。
这是JPA中的默认openjpa.LockManager设置。
可以使用悲观锁定管理器及其属性覆盖此设置:
悲观的LockManager可以配置为另外执行 版本锁的版本检查和递增行为 经理通过设置其VersionCheckOnReadLock和来描述 VersionUpdateOnWriteLock属性。
所以我将OpenJPA配置为不更改更新版本:
<property name="openjpa.LockManager" value="pessimistic(VersionCheckOnReadLock=true,VersionUpdateOnWriteLock=false)"/>
但它不起作用。所有子项的版本字段仍会递增。我错过了什么吗?为了让OpenJPA仅更新已更改实体的版本字段,我需要配置什么?
答案 0 :(得分:1)
问题是不正确的equals()和hashcode()实现,因此EntityManager假定列表中的所有实体都已更改。