Hibernate乐观锁定异常

时间:2016-03-30 08:41:10

标签: hibernate spring-mvc jpa java-ee

我在WebApp中遇到以下错误:

Handling an unexpected exception in webApp: - javax.servlet.error.status_code = 500 - javax.servlet.error.exception_type = class org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException - javax.servlet.error.message = Object of class [domain.entity.common.dataEntity] with identifier [110837262]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [domain.entity.common.dataEntity

我不确定为什么会出现这种错误,它发生在下面一行。

SpecEntity specTemp = this.persistService.merge(specTemp);

有人可以帮忙吗。

1 个答案:

答案 0 :(得分:7)

在这种情况下,当您尝试在另一个事务已经同时更新的HibernateOptimisticLockingFailureException(specTaskTemp)上调用merge时,会发生entity异常。

如果查看SpecEntity课程,则必须定义@Version列。 hibernate将使用它来检查您合并的实体是否比数据库中的实体旧。

样本流程:

  1. 事务T1加载版本列值为
  2. SpecEntity实体
  3. 事务T2使用版本值1加载相同的SpecEntity
  4. T2对此实体进行一些更改并更新数据库,因此版本值变为2.
  5. 随后T1尝试更新实体。
  6. Hibernate检查实体中的版本(即1)是否与数据库中的值相同(更新为2)。
  7. 当发现不匹配时,它会抛出HibernateOptimisticLockingFailureException
  8. 根据您的使用情况,您可以从数据库重新加载更新的entity并向用户显示updated data,以便用户可以决定下一步该做什么。

    或者,如果要继续使用specTaskTemp实体中的数据覆盖数据库中的数据,可以从数据库中获取此实体的最新版本,将其版本值复制到specTaskTemp实体,然后调用merge调用。