当分离的实体版本属性为null时,为什么Hibernate entitymanager执行insert而不是update?

时间:2015-02-04 19:32:55

标签: java hibernate jpa orm

我注意到当你有一个具有@Version属性的实体并且你试图通过手动实例化实体来更新记录,将其id设置为现有id并调用merge()时,Hibernate执行插入而不是更新。我假设这是因为手动实例化对象的version属性为null。是否存在足以让Hibernate确定它应该执行更新的标识符?

示例代码:

假设数据库中存在id = 1的记录,而MyEntity具有@Version的属性版本。

MyEntity e = new MyEntity();
e.setId(1);
e.setName("some updated value");

entityManager.merge(e);

这最终会执行插入而不是更新。

MyEntity就像:

@Entity
public class MyEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer id;

    @Column("name")
    String name;

    @Version
    Integer version;

}

如果删除@Version,它会按预期工作,更新id = 1的记录。

1 个答案:

答案 0 :(得分:4)

The documentation确认了您的体验:

  

对于分离的实例,版本或时间戳属性永远不应为null。无论指定了什么其他未保存值策略,Hibernate都会将具有null版本或时间戳的任何实例检测为瞬态。

即使它使用ID来确定实体是否已分离,尝试将实体与null版本合并将导致乐观锁定异常。您根本不应该使用null版本合并分离的对象。这违背了使用乐观锁定的目的。