【问题标题】:jpa creating new entity while deleting old one that has the same primary key valuejpa 创建新实体,同时删除具有相同主键值的旧实体
【发布时间】:2015-02-02 15:56:48
【问题描述】:

考虑这样一种情况:用户删除具有主键值 x 的实体 A,然后在同一事务中插入另一个具有相同主键值 x 的实体。然后提交事务。 A 有一个版本字段。因此,新创建实体的版本字段为零
发生乐观锁定异常,说明在事务提交时,具有主键 x 的实体 A 可能已被更新或删除。 我试过工作单元点应该先执行删除,但会出现相同的结果。 有没有办法告诉 jpa 这是一个新实体。

【问题讨论】:

  • 为什么先插入再删除?能不能不更新一下?
  • 它是一个新实体吗?如果实体仍然具有相同的 ID - 它是相同的实体,对吗?
  • 您是否在这些实体中覆盖了 equals?
  • 在同一个 EntityManager 中同时存在 2 个具有相同 id 的实体违反了 JPA 规范。唯一接近的就是获取已删除的实体并重新保留它。
  • 我正在使用 unsync 扩展实体管理器,然后在用户按下保存按钮时加入事务。用户可以删除实体,然后创建另一个具有相同 ID 的实体。这些东西对用户/测试者没有意义。所以这个案子是真实的

标签: java jpa eclipselink


【解决方案1】:

这是一种罕见的情况,您可能想先尝试刷新您的删除(这也会分离受影响的实体),然后再将新实体保留在同一事务中。否则,您希望您的持久性提供者能够容忍持久性上下文中具有完全相同身份的两个不同实体的共存。我认识的任何持久性提供者都不会允许这种情况。正如 esej 上面指出的那样,任何提供者都会将具有相同 id 的每个实体实例视为代表相同的实体,因此在给定时间在持久性上下文中只允许存在一个引用。在您的特殊情况下,新实体的持久化操作会导致实体的替换在持久化上下文中被删除,甚至在删除操作提交并实际发生之前。因此,在提交时,提供者唯一尝试做的就是使用您的新实体更新数据库。抛出乐观锁异常也就不足为奇了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 1970-01-01
    • 2018-01-16
    • 2019-11-18
    • 1970-01-01
    • 2015-09-01
    相关资源
    最近更新 更多