我注意到当你有一个具有@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的记录。
答案 0 :(得分:4)
The documentation确认了您的体验:
对于分离的实例,版本或时间戳属性永远不应为null。无论指定了什么其他未保存值策略,Hibernate都会将具有null版本或时间戳的任何实例检测为瞬态。
即使它使用ID来确定实体是否已分离,尝试将实体与null版本合并将导致乐观锁定异常。您根本不应该使用null版本合并分离的对象。这违背了使用乐观锁定的目的。