【问题标题】:Will JPA EntityManager's merge method lead to OptimisticLockException?JPA EntityManager的merge方法会导致OptimisticLockException吗?
【发布时间】:2014-04-06 14:01:14
【问题描述】:

假设我想合并一个分离的实体。 当我这样做时

T mergedEntity = entityManager.merge(detachedEntity);

entityManager 将从数据库加载一个实体(与 detachedEntity 具有相同的标识符)并将所有数据从 detachedEntity 复制到新加载的实体。当稍后我的事务结束时,这个实体将被保存到数据库中。

但是,在并发场景中,数据库中的实体可以被其他事务更新,该实体首先加载到我的事务中,然后在我的事务结束时刷新。 在这种情况下,我想知道是否会抛出 OptimisticLockException ?如果是这样,为什么合并 API 没有在 Java 文档中指定 OptimisticLockException? http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#merge(T)

谢谢

【问题讨论】:

  • 我认为合并不会从数据库中检索生成的托管实体,而只会克隆给定的分离实例。 AFAIK无论如何都会在启用乐观锁定时检索版本值。我希望@JB Nizet 确认他是否不介意。

标签: java jpa


【解决方案1】:

因为merge() 方法不会引发此异常。当内存中的实体状态刷新到数据库时,将引发此异常。当merge() 被调用,flush() 被调用时,无论是显式调用,还是在提交之前,或者在执行查询之前,都不会发生这种情况。

【讨论】:

  • 感谢您提醒合并不会刷新数据库。这应该在交易结束时发生
【解决方案2】:

JPA EntityManager 的 merge 方法会导致 OptimisticLockException 吗?

不,不直接。

我想知道是否会出现 OptimisticLockException 抛出?如果是这样,为什么合并 API 没有指定 Java 文档中的 OptimisticLockException?

OptimisticLockException 显然只有在您配置了乐观锁定的情况下才会被抛出。此外,由于它继承自 java.lang.RuntimeExceptionmerge 方法无论如何都不必声明它。

但这都是假设的,因为OptimisticLockException 在合并阶段甚至没有被抛出,而是在刷新对数据源的更改时。

【讨论】:

  • OptimisticLockException 继承 RuntimeException 可能不是没有在方法中声明的原因,因为 EntityManager 的查找和锁定方法确实声明了 OptimisticLockException。我认为原因正如您和其他人所说,合并不会直接导致问题。同样感谢!
猜你喜欢
  • 2016-11-05
  • 2019-03-30
  • 1970-01-01
  • 2010-11-07
  • 2012-05-25
  • 1970-01-01
  • 2011-09-26
  • 2011-08-23
  • 2012-04-11
相关资源
最近更新 更多