避免“具有相同标识符值的不同对象已与会话关联”的最佳实践

问题描述 投票:0回答:1

我认为这是一个常见的程序

  • 通过休眠加载实体
  • 将其存储在会话变量中
  • 更改属性
  • 稍后保存

在任何情况下,当当前会话已经加载对象时,避免错误

A different object with the same identifier value was already associated with the session
的常见做法是什么?

  • 使用合并?
  • 避免之前加载相同的对象?
  • 刷新休眠会话并分离另一个实例?
  • 从会话中检索对象并手动从会话中的实例复制更改?
  • 使用 DTO 并仅将 id 存储在会话处理程序中?
  • 还有其他想法吗?
hibernate jpa
1个回答
0
投票

我认为最佳实践是非常固执己见的。最后,您必须选择最适合您的用例的方法。我个人使用了以下方法:

  • 使用
    EntityManager.merge
    - 它有效且简单,但您必须在要合并的关联上正确配置
    CascadeType.MERGE
    或进行单独合并。但这可能并不适合所有用例,并会导致大量更新
  • 从会话中获取当前对象并应用更改 - 如果我想完全控制可以更改的内容,并且当我看到某些属性值更改时可能会触发一些其他更改,我通常会这样做,但需要编写大量繁琐的代码
  • 使用 DTO - 这类似于“从会话获取当前对象并应用更改”,因为您必须以某种方式将 DTO 映射到实体

话虽如此,我更喜欢使用 DTO 方法,但使用 Blaze-Persistence Entity Views,它支持脏跟踪以仅更新真正更改的内容。

我创建了这个库,以允许在 JPA 模型和自定义接口或抽象类定义的模型之间轻松映射,就像类固醇上的 Spring Data Projections 一样。这个想法是,您按照自己喜欢的方式定义目标结构(域模型),并通过 JPQL 表达式将属性(getter)映射到实体模型。

查看文档以获取更多信息:https://persistence.blazebit.com/documentation/1.5/entity-view/manual/en_US/#updatable-mappings-basic

默认的刷新策略使用 DML 查询,因此除了持久化对象之外,不与持久化上下文/会话进行交互,但是还有一个实体刷新策略,如果需要的话,可以通过更改持久化上下文中的对象来工作。

© www.soinside.com 2019 - 2024. All rights reserved.