Hibernate乐观锁异常

3
我在WebApp中遇到以下错误:
处理WebApp中的意外异常: - javax.servlet.error.status_code = 500 - javax.servlet.error.exception_type = class org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException - javax.servlet.error.message = 具有标识符 [110837262] 的类对象 [domain.entity.common.dataEntity]:乐观锁定失败; 嵌套异常为 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个回答

11
在这种情况下,HibernateOptimisticLockingFailureException异常表示当您尝试调用merge方法时,该方法作用于的entity(specTaskTemp)已经被另一个事务更新过了。
如果您查看SpecEntity类,必须定义@Version列。Hibernate将使用此列来检查您正在合并的实体是否比数据库中的旧。
示例流程:
  1. 事务T1加载版本值为x的SpecEntity实体。
  2. 事务T2加载相同的SpecEntity实体,版本值为1。
  3. T2对此实体进行一些更改并更新数据库,因此版本值变为2。
  4. 随后,T1尝试更新该实体。
  5. Hibernate检查实体中的版本(即1)是否与数据库中的值(已更新为2)相同。
  6. 当它发现不匹配时,就会抛出HibernateOptimisticLockingFailureException异常。
根据您的使用情况,您可以重新从数据库中加载已更新的entity,并向用户显示updated data,以便用户决定下一步该怎么做。
或者,如果您想要继续使用specTaskTemp实体中的数据覆盖数据库中的数据,您可以从数据库中获取此实体的最新版本,将其版本值复制到specTaskTemp实体中,然后调用merge方法。

谢谢回复。我想知道的是,为什么GenDataEntity作为SpecEntity的扩展会抛出错误。如果在同一会话中有merge或persist操作,是否会发生这种情况。我们能否通过数据库中的ID-110837262跟踪陈旧对象。 - Tiny
@Teena 不确定我是否可以在查看您的领域模型和应用程序流程之前回答这个问题。现在,既然您知道了问题的关键所在以及何时可能会出现此异常,您可以启用show_SQL属性并查看导致问题的确切事件序列。 - Madhusudana Reddy Sunnapu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接