我在Family
和Person
之间进行了双向映射:
@Entity class Family {
@OneToMany(mappedBy = "family", ...)
Set<Person> persons;
...
}
@Entity class Person {
@ManyToOne
Family family;
...
}
我的问题是我可以同时添加和/或删除集合中的元素,这会在更新中破坏原子性,因为添加新人会创建不会与其他插入冲突的INSERT INTO Person ...
语句。 @Version
字段无效,因为我没有将Family
实体更新为表格中的行,只是逻辑上。
如何仅启用集合的原子更新?我已尝试使用Family
加载LockMode.PESSIMISTIC_WRITE
,Family
可以同步Family
本身的更新,但不允许读取 d3.select("svg")
.append("foreignObject")
.attr("width", 480)
.attr("height", 500)
的第二级缓存。我更喜欢在数据库中使用谓词约束的乐观事务。
答案 0 :(得分:2)
您可以使用OPTIMISTIC_FORCE_INCREMENT:
entityManager.lock(family, LockModeType.OPTIMISTIC_FORCE_INCREMENT);
这种方式将在相应的Family
实体实例中检查并递增。
修改强>
由于您正在使用L2缓存,并且由于某种原因(错误,设计决策或仅缺少功能)Hibernate在强制增量后不更新L2缓存中的版本,您将不得不实际加载实体锁定一切正常工作:
entityManager.find(Family.class, id, LockModeType.OPTIMISTIC_FORCE_INCREMENT);
但是,现在您必须注意保持一致并在更新它们之前始终以这种方式加载Family
实体(以避免使用过时的版本值,因为L2缓存与数据库不同步)。
要解决此问题,您可以向Family
实体添加人工列,例如lastUpdateTime
或其他内容,并在不使用任何显式锁定的情况下更新Family
实例。然后将进行常规版本检查,并且所有内容都将与L2缓存同步。