【发布时间】:2023-12-29 12:45:01
【问题描述】:
客户端应用程序提供了一个陈旧的实体,该实体将被 Hibernate 合并。举个很简单的例子。
public Entity update(Entity entity) {
return entityManager.contains(entity) ? entity : entityManager.merge(entity);
}
Entity 是一个分离的、陈旧的实体,例如,由 Web 应用程序提供。该方法在活动的 JTA 事务(或本地资源)中执行。
已通过在给定实体中引入@Version 字段来启用乐观锁定。
当要合并的实体已经被删除时,javax.persistence.OptimisticLockException 预计会被抛出,但不会发生。 Hibernate 执行INSERT,这完全出乎意料。插入一个过时的实体而不是抛出 javax.persistence.OptimisticLockException 是违反锁定的。
“插入或更新”是一个单独的故事,如果将过时或已删除(不存在)的实体传递给merge(),则应通过抛出javax.persistence.OptimisticLockException 暂停该故事,如果实施了乐观锁定。
EclipseLink 会按预期抛出javax.persistence.OptimisticLockException,以防将过时或已删除/不存在的实体传递给merge()。
当一个陈旧或不存在的实体被传递给merge()时,有没有办法让Hibernate抛出javax.persistence.OptimisticLockException?
我希望persistence.xml 中应该有一些可配置的属性以将其应用于全局应用程序范围或注释以将其应用于特定实体。
我目前使用的是 Hibernate 5.0.5 final。
更新到 Hibernate 5.0.6 final。
【问题讨论】:
-
这是一个长期存在的 Hibernate 错误。你可以投票给它:hibernate.atlassian.net/browse/HHH-1661
-
这个问题大约有十年的历史了。
-
我认为,应该创建一个新的、新鲜的问题。该问题报告不太可能被考虑在内,因为它已经很老了。这是一个不能掉以轻心的严重bug,需要尽快修复。
-
它已针对 Hibernate 5 进行了更新,因此在进行大型 JIRA 清理时保留在未解决的错误中,它是精确的、有投票的和可重现的测试用例。打开一个新的相同错误将消除该错误或注意力,或者被标记为重复。
标签: hibernate jpa merge optimistic-locking