Java 我可以使用@Version字段自动检查并发修改吗?
我有一个带有注释的Java 我可以使用@Version字段自动检查并发修改吗?,java,hibernate,jpa,locking,Java,Hibernate,Jpa,Locking,我有一个带有注释的@Version字段的实体。在前端显示数据时,我试图使用此字段检查对实体的并发修改。然而,这似乎没有产生预期的效果 @Entity public class User { @Id @GeneratedValue(strategy=GenerationType.TABLE, generator="UUIDGenerator") @Column(name="id") private Long id; @NotNull private String use
@Version
字段的实体。在前端显示数据时,我试图使用此字段检查对实体的并发修改。然而,这似乎没有产生预期的效果
@Entity
public class User
{
@Id
@GeneratedValue(strategy=GenerationType.TABLE, generator="UUIDGenerator")
@Column(name="id")
private Long id;
@NotNull
private String username;
private String password;
@Version
@Column(name="version")
private Integer version;
}
我要求前端在发布数据时将version
字段发送回服务器。在服务器端,我使用PK从数据库检索实体,用发布的值更新版本(以及其他字段),然后让entitymanager持久化实体。我希望,如果同时版本发生更改,它会自动抛出StaleObject异常,但它什么也不做
进一步阅读后,似乎不允许我以编程方式修改版本字段。根据JPA规范,应用程序不允许修改版本字段: JPA 2.0最终规范,第3.4.2节: 实体可以访问其版本字段或属性的状态,或者 导出方法以供应用程序用于访问版本,但 不能修改版本值。除第节所述的例外情况外 4.10中,仅允许持久性提供程序设置或更新对象中版本属性的值
在这一点上,我唯一的选择是每次手动检查发布数据的版本与DB的版本吗?难道没有办法让JPA提供商为我这样做吗?为什么不使用JPA EntityManager的合并方法 此方法将首先将实体提取到持久化上下文,并将所有值从实体(分离)复制到持久化实体。当事务刷新时,JPA将为您检查版本。如果它过时,将抛出乐观锁异常。使用此方法,实际上不需要自己检查版本 乐观锁定是一种用于确保更新 与实体状态相对应的数据库数据 仅当自 实体状态被读取 如果该规则被破坏,则抛出的异常是OptimisticLockException 其中一些是考虑因素
我考虑过使用它,但这意味着整个实体正在合并。为了做到这一点,因为我想从客户端复制选择性字段,我必须首先从数据库中检索实体,分离它,然后合并它。这种做法违背了JPA坚持的“魔力”,即不需要每次都指导它坚持下去。虽然我并没有告诉它要持久化,但在这个上下文中,合并几乎是一样的。如果您只想持久化某些属性,那么可以将持久化实体提取到持久化上下文中,并手动将这些属性复制到其中。我认为JPA会在交易结束时为您处理剩下的事情(比如版本)。版本只是维护优化锁的机制之一(我听说其他一些持久性框架可能使用时间戳而不是版本),因此最好让持久性框架为您管理优化锁,但不要直接接触它;但是,当您检索数据并将其发送给客户机时,客户机在将数据发送回您之前需要花费一些时间,您需要确保数据库上的数据自那时起没有更改。因此,即使我可以从数据库中检索行并直接更新它(通过将字段复制到该实体中),我也必须首先确保正在更新的行的版本与客户端返回的版本相同(即:在此期间没有人修改该行)。因此需要使用
@Version
字段。