当一个不存在的实体被传递给 merge() 时,Hibernate 意外地发出 INSERT 而不是抛出 javax.persistence.OptimisticLockException

标签 hibernate jpa merge optimistic-locking

客户端应用程序提供了一个陈旧的实体,该实体将被 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是反对锁定的东西。

“插入或更新”是一个故事,应该通过抛出 javax.persistence.OptimisticLockException 暂停。 , 如果一个陈旧或已删除(不存在)的实体被传递给 merge() , 如果实现了乐观锁。

EclipseLink 抛出 javax.persistence.OptimisticLockException正如预期的那样,以防将陈旧或已删除/不存在的实体传递给 merge() .

有没有办法让 Hibernate 抛出 javax.persistence.OptimisticLockException ,当一个陈旧或不存在的实体被传递给 merge() ?

我希望 persistence.xml 中应该有一些可配置的属性将其应用于全局应用程序范围或注释以将其应用于特定实体。

我目前使用的是 Hibernate 5.0.5 final。

更新到 Hibernate 5.0.6 最终版。

最佳答案

尝试使用 EntityManager.refresh 代替 EntityManager.merge,并验证实体是否具有 id 值,如果是则设置新值,在 EntityManager.merge 之后,如果没有实体已被删除

像这样的东西

public Entity update(Entity entity) {

    entityManager.refresh(entity);

    if (entity.getId() != null) {
        // my entity is in database
        // set my changes in entity
        return entityManager.merge(entity);
    } else {
        // my entity has been deleted
        return null;
    }
}

关于当一个不存在的实体被传递给 merge() 时,Hibernate 意外地发出 INSERT 而不是抛出 javax.persistence.OptimisticLockException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34249483/

相关文章:

java - 如何在 persistence.xml 文件中包含外部实体

java - Hibernate删除和更新

java - Hibernate + Spring + Maven(框架设置问题)

java - session.clear() 是必要的吗?

java - 在 Eclipse 链接中使用历史策略跟踪更改

R cbind xts 对象导致添加/重复行

java - 在 JPA 实体上实现 "touch"?

java - 双向 JPA 映射时 Spring REST 返回递归 JSON

python - 如何合并/合并 Pandas 中的列?

java - 如何以最快的方式将两个排序数组相交?