gpt4 book ai didi

java - JPA 乐观锁定规范是否支持根据客户端提供的版本进行验证

转载 作者:行者123 更新时间:2023-11-30 06:10:11 24 4
gpt4 key购买 nike

假设我有一个定义如下的实体:

@Entity
public class MyEntity {
@Id
@GeneratedValue
private Integer id;

@Column
private String name;

@Version
int version;

// Getters + setters
}

假设我有一个服务(REST API 或类似的东西),允许用户检索有关该实体的信息。它返回 ID、当前名称和当前版本。还有另一种服务允许用户更新实体的名称。它接受 ID、更新名称和版本作为输入参数。因此可以通过创建新对象并使用合并来更新实体:

public MyEntity update(EntityManager em, int id, String name, int version) {
MyEntity entity = new Entity();
entity.setId(id);
entity.setName(name);
entity.setVersion(version);
return em.merge(entity);
}

或者可以通过从数据库检索并仅更新相关字段来更新它:

public MyEntity update(EntityManager em, int id, String name, int version) {
MyEntity entity = em.find(MyEntity.class, id);
entity.setName(name);
entity.setVersion(version);
return entity;
}

我的测试告诉我,在 Hibernate 5.3 中,如果提供的第一个场景将抛出 OptimisticLockException(带有消息行已被另一个事务更新或删除(或未保存值映射不正确))版本与数据库中的版本不匹配。但是,第二种情况工作正常,并且无论提供的版本如何,名称都会更新。

我还在 DataNucleus 5.1.9 上尝试过此操作,两种情况都不会引发异常,并且无论两种情况下提供的版本如何,名称都会更新。

所以我猜要么是 Hibernate 或 DataNucleus 中存在错误,其中之一不遵循 JPA 规范,要么规范没有明确指定它应该如何工作?

我试图找到这个问题的明确答案,但未能成功。有人可以确认,根据 JPA 规范,在更新具有外部提供的版本号的实体时,乐观锁定应该如何工作?

最佳答案

Eeeek,外部设置@Version字段?在大多数情况下,这可能会导致冲突,因为它不应该由开发人员设置。它由持久性提供者专门管理。您不需要 getter 也不需要 setter 来访问 version

JPA 2.0 规范摘录:

The Version field or property is used by the persistence provider to perform optimistic locking. It is accessed and/or set by the persistence provider in the course of performing lifecycle operations on the entity instance. An entity is automatically enabled for optimistic locking if it has a property or field mapped with a Version mapping. An entity may access the state of its version field or property or export a method for use by the application to access the version, but must not modify the version value[34]. With the exception noted in section 4.10, only the persistence provider is permitted to set or update the value of the version attribute in the object.

关于更新过程:您通常会从 Rest Interface 检索对象的 ID 以及要更改的数据。您将两者传递给 Service,在其中告诉 EntityManager 获取具有给定 ID 的实体,更新该实体的数据,并告诉 EntityManager 立即将其保存回来。这个过程并不是一成不变的,但在大多数情况下大致就是这样完成的。

实体上的 setID()setVersion() 方法很可能都是不好的做法。

关于java - JPA 乐观锁定规范是否支持根据客户端提供的版本进行验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50420000/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com