【问题标题】:JPA merge will load latest version from persistence?JPA 合并将从持久性中加载最新版本?
【发布时间】:2018-01-29 22:18:21
【问题描述】:

假设一个分离的实体 foo,它的版本是 10。另一个用户改变了 Foo,它的版本在数据库中变成了 11。

em.merge(foo)

一些 JPA 提供程序(例如 Hibernate)将从持久性加载实体并将分离的 foo 的更改复制到实体(托管)。加载相同版本或最新版本的实体?在合并时或刷新时抛出乐观锁异常?

【问题讨论】:

    标签: jpa merge


    【解决方案1】:

    根据Vlad Mihalcea's blog

    ...要将分离的实体关联到活动的 Hibernate Session,您可以选择以下选项之一:

    1. 重新附加 Hibernate(但不是 JPA 2.1)支持通过重新附加 Session#update 方法。

      Hibernate Session 只能关联一个给定的实体对象 数据库行。这是因为持久性上下文充当 内存缓存(一级缓存),只有一个值(实体) 关联到给定的键(实体类型和数据库标识符)。

      只有在没有其他 JVM 对象时才能重新附加实体 (匹配相同的数据库行)已经关联到当前 休眠会话。

    2. Merging 合并操作将复制分离的实体 状态(源)到受管实体实例(目标)。如果 合并实体在当前会话中没有等价物,一个将是 从数据库中获取。

    即使在合并操作之后,分离的对象实例也将继续保持分离状态。

    因此,如果您处于第二种情况,并且 Session 没有相关的托管实体,则会触发调用以检索全新的实体。由于读取不是事务性的,因此您无法锁定任何内容。

    【讨论】:

    • 要加载哪个版本的实体?数据库中的最新版本还是分离实体的版本?
    • 这取决于当前会话中的内容。如果没有托管的,这是 jpa 搜索任何东西的第一个地方,它会尝试 db。
    • 如上例,如果不托管,会取10版还是11版?
    • 如果我理解得很好,在数据库中有 11 个……所以将是 11 个。
    • 用户根据版本10进行了更改,但是如果加载版本11,会不会导致意外的结果?
    猜你喜欢
    • 2015-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多