我可以使用@Version字段自动检查并发修改吗?

时间:2014-04-17 02:48:50

标签: 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 username;
  private String password;

  @Version
  @Column(name="version")
  private Integer version;
}

我要求前端在发布数据时将version字段发送回服务器。在服务器端,我使用PK从数据库中检索实体,使用发布的值更新版本(以及其他字段),然后让实体管理器持久保存实体。我希望如果版本在此期间发生了变化,它会自动抛出StaleObject异常,但它什么也没做。

进一步阅读后,似乎不允许我以编程方式修改版本字段 根据JPA规范,不允许应用程序修改版本字段:

  

JPA 2.0最终规范,第3.4.2节:

     

实体可以访问其版本字段或属性的状态或   导出应用程序使用的方法来访问该版本,但是   不得修改版本值。除了节中提到的例外情况   4.10,只允许持久性提供程序设置或更新对象中version属性的值。

此时我唯一的选择是每次自己手动检查发布数据的版本与数据库的版本吗?有没有办法让JPA提供商为我做这个?

2 个答案:

答案 0 :(得分:0)

为什么不使用JPA EntityManager的合并方法?

http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#merge(T)

此方法将首先将实体提取到持久化上下文,并将实体(已分离)中的所有值复制到持久化实体。刷新事务时,JPA将为您检查版本。如果它是陈旧的,将抛出一个OptimisticLockException。使用此方法,您无需自行检查版本

答案 1 :(得分:0)

实际上

  

乐观锁定是一种用于确保更新的技术   对数据库进行与实体状态对应的数据   只有当干预交易没有更新该数据时才会发生   实体国家已被阅读。

如果此规则被破坏,则抛出异常是一个OptimisticLockException。

一些考虑因素。

  1. 您的提供商应支持乐观锁定。
  2. 您可以调用某种方法来启用此类锁定。

    lock(java.lang.Object实体,LockModeType lockMode)

    find(java.lang.Class entityClass,java.lang.Object primaryKey,LockModeType lockMode)

    refresh(java.lang.Object entity,LockModeType lockMode)