合并父实体时,所有子项的版本在OneToMany中递增

时间:2011-08-03 07:36:45

标签: java jpa entity-relationship openjpa

我有一个像这样定义的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仅更新已更改实体的版本字段,我需要配置什么?

1 个答案:

答案 0 :(得分:1)

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