我的应用程序正在使用 Spring Data JPA (Hibernate)。该应用程序公开了一个 REST API,它允许操作持久性存储中的数据(使用 Hibernate)。
如果(应用程序的)REST 客户端想要更新某些内容,他将随数据一起发送实体的预期版本号。有一个 RFC 可以解决这个问题,但这不是这里的重点。底线:我得到一些“预期版本”值以及
PUT
或 PATCH
操作。
我的实体看起来像这样:
@Entity
public class Person {
@Version
@Column(name="entity_version")
private Long version;
// getters and setters
}
在传入
PUT
或 PATCH
操作时,我这样做:
person.setVersion(expectedVersionReceivedFromRestClient)
设置“预期版本”。repo.save(entity)
。现在,如果 REST 客户端发送一些非常奇怪的长数字作为预期版本,我会假设我会得到一个
OptimisticLockException
。然而,这并没有发生。
我已经调试过,看来 Hibernate 会在合并之前刷新实体。因此,我用
setVersion()
设置的值会丢失,因此合并操作始终会成功。不是我所期望的!
我读过各种文档,说我不应该在任何
@Version
带注释的属性上手动调用设置值。但是我如何才能将无状态 REST 世界与 JPA 模型结合起来呢?
我想我有这个问题,但我必须承认,我不明白其中任何一个。 :-(
该版本由 Hibernate 管理,需要防止在并行事务中更新实体。 GET 和 PUT 请求之间发生的事情不是数据库事务,因此您不应该以这种方式解决它。 Hibernate doc 说:禁止您的应用程序更改 Hibernate 设置的版本号。
如果需要,您可以手动检查请求的版本是否等于现有实体的版本。但在我看来,
@CreatedDate
更适合这种情况,因为它是人类可读的。