【问题标题】:Version of all children is incremented in OneToMany when merging parent entity合并父实体时,OneToMany 中所有子实体的版本都会递增
【发布时间】: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


    【解决方案1】:

    问题在于不正确的 equals() 和 hashcode() 实现,因此 EntityManager 假定列表中的所有实体都已更改。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-17
      • 2015-10-14
      • 2020-04-19
      • 1970-01-01
      • 1970-01-01
      • 2019-07-27
      • 2011-11-19
      • 1970-01-01
      相关资源
      最近更新 更多