合并父实体时,OneToMany 中所有子实体的版本都会增加
我有一个 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) 完成合并,所有子元素的版本都会增加 1!我预计更改后的子项的版本只会增加。首先,我认为这是因为我的 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 仅更新更改的实体的版本字段,我必须配置什么?
I have a OneToMany relationship defined like this:
@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;
// ...
}
The @Version annotation is defined in the BaseEntity class. The entities are converted to DTOs and changed by the client. Now when the client changes one of the child elements, the parent and its children are converted back to entities and a merge is done by executing em.merge(parent), the version of ALL children is incremented by one! I expected that the version of the changed child is incremented only. First I thought it is because of my EntityCallbackListener which is intercepting the merge with @PreUpdate. But if I comment out the callback method the version fields of the other children are still incremented. Does anyone have an explanation for this behaviour?
I'm using OpenJPA 1.2.3.
Okay, RTFM sometimes helps... :-/
Increasing the version on all children is OpenJPA default:
This lock manager does not perform any exclusive locking, but instead
ensures read consistency by verifying that the version of all
read-locked instances is unchanged at the end of the transaction.
Furthermore, a write lock will force an increment to the version at
the end of the transaction, even if the object is not otherwise
modified. This ensures read consistency with non-blocking behavior.This is the default openjpa.LockManager setting in JPA.
This setting can be overriden by using the pessimistic lock manager and its properties:
The pessimistic LockManager can be configued to additionally perform
the version checking and incrementing behavior of the version lock
manager described below by setting its VersionCheckOnReadLock and
VersionUpdateOnWriteLock properties.
So I configured OpenJPA to not change the version on update:
<property name="openjpa.LockManager" value="pessimistic(VersionCheckOnReadLock=true,VersionUpdateOnWriteLock=false)"/>
But it does not work. The version fields of all children are still incremented. Do I miss something? What do I have to configure in order to have OpenJPA update the changed entities' version field only?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题是 equals() 和 hashcode() 实现不正确,因此 EntityManager 假设列表中的所有实体都已更改。
The problem was a incorrect equals() and hashcode() implementation so the EntityManager assumed all entities in the list had been changed.