【发布时间】:2011-08-03 07:36:44
【问题描述】:
我有一个这样定义的 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(parent) 完成合并,所有子元素的版本都加一!我预计更改后的子版本只会增加。首先,我认为这是因为我的 EntityCallbackListener 拦截了与 @PreUpdate 的合并。但是如果我注释掉回调方法,其他孩子的版本字段仍然会增加。有人对此行为有解释吗?
我正在使用 OpenJPA 1.2.3。
好的,RTFM 有时会有所帮助... :-/
在所有子节点上增加版本是 OpenJPA 默认的:
这个锁管理器不执行任何排他锁,而是 通过验证所有的版本来确保读取一致性 读锁定实例在事务结束时保持不变。 此外,写锁将强制增加版本 事务的结束,即使对象不是,否则 修改的。这确保了读取与非阻塞行为的一致性。
这是 JPA 中的默认 openjpa.LockManager 设置。
可以使用悲观锁管理器及其属性覆盖此设置:
悲观的 LockManager 可以配置为额外执行 版本锁的版本检查和递增行为 下面描述的管理器通过设置其 VersionCheckOnReadLock 和 VersionUpdateOnWriteLock 属性。
所以我将 OpenJPA 配置为在更新时不更改版本:
<property name="openjpa.LockManager" value="pessimistic(VersionCheckOnReadLock=true,VersionUpdateOnWriteLock=false)"/>
但它不起作用。所有孩子的版本字段仍然递增。我错过了什么吗?为了让 OpenJPA 仅更新已更改实体的版本字段,我必须进行哪些配置?
【问题讨论】:
标签: java jpa entity-relationship openjpa