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

时间:2015-12-13 08:58:20

标签: 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()来暂停。< / p>

如果将陈旧或已删除/不存在的实体传递给javax.persistence.OptimisticLockException,EclipseLink会按预期抛出merge()

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

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

我目前正在使用Hibernate 5.0.5 final。

更新到Hibernate 5.0.6 final。

1 个答案:

答案 0 :(得分:0)

尝试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;
    }
}