将分离的实体合并到 JPA 中的实体管理器的最佳方法是啥
Posted
技术标签:
【中文标题】将分离的实体合并到 JPA 中的实体管理器的最佳方法是啥【英文标题】:What is best way to merge detached entities to entity manager in JPA将分离的实体合并到 JPA 中的实体管理器的最佳方法是什么 【发布时间】:2014-11-24 12:33:30 【问题描述】:我正在使用 JPA + spring 开发 Web 应用程序。我的项目层结构是web --> service --> DAO--> GenericDAO。所有类都被实例化为单例 spring bean。 GenericDAO 正在使用 @PersistenceContext 注入 entityManager 的实例。
我的应用程序在 http 会话中获取存储中的域实体。在我对这些实体执行任何数据库操作之前,需要使用合并将它重新附加到实体管理器。我想知道将实体合并到实体管理器的最佳方式。目前,每次调用事务方法时,我都会调用 genericDAO.merge(object)。 例如
@Transactional
public void addProducts()
Order order = getOrderFromHttpSession();
genericDAO.merge(order);
// delete existing products
// add new products
// other db operations.
有没有其他更好的方法来做到这一点。任何设计模式都可用于此?
【问题讨论】:
【参考方案1】:我认为这是最好的方法。出于这个原因,JPA 提供了这种方法。
/**
* Merge the state of the given entity into the
* current persistence context.
* @param entity entity instance
* @return the managed instance that the state was merged to
* @throws IllegalArgumentException if instance is not an
* entity or is a removed entity
* @throws TransactionRequiredException if invoked on a
* container-managed entity manager of type
* <code>PersistenceContextType.TRANSACTION</code> and there is
* no transaction
*/
public <T> T merge(T entity);
3.2.4.1 合并分离实体状态
合并操作允许 从分离状态传播 实体到持久实体 由 EntityManager 管理。
合并操作的语义 应用于实体 X 如下:
如果 X 是分离的实体,则 X 的状态将复制到预先存在的 相同的托管实体实例 X' 身份或 X 的新托管副本 X' 已创建。 如果 X 是一个新的实体实例,则创建一个新的托管实体实例 X' X 的状态被复制到 新的托管实体实例 X'。 如果 X 是已删除的实体实例,则IllegalArgumentException
将是 由合并操作(或 事务提交将失败)。 如果 X 是一个托管实体,它会被合并操作忽略, 但是,合并操作是 级联到引用的实体 来自 X 的关系,如果这些 关系已用 级联元素值cascade=MERGE
或cascade=ALL
注释。 对于由来自 X 的关系引用的所有实体 Y,具有 级联元素值cascade=MERGE
或cascade=ALL
,Y递归合并 作为 Y'。对于所有这样的 Y 引用 X, X' 设置为参考 Y'。 (笔记 如果 X 是托管的,那么 X 是 与 X' 相同的对象。) 如果 X 是合并到 X' 的实体,并引用另一个实体 Y,其中cascade=MERGE
或cascade=ALL
是 未指定,则导航 来自 X' 的相同关联产生 对托管对象 Y' 的引用 与 Y 相同的永久身份。持久性提供者不得 合并标记为 LAZY 的字段 已获取:它必须忽略此类 合并时的字段。
任何
Version
使用的列 实体必须由 持久性运行时实现 在合并操作期间和/或在 刷新或提交时间。离席期间Version
列中没有 额外的版本检查由 持久性提供程序运行时 在合并操作期间。
另一种方法是 em.find(someKey) 并复制每个更改的信息。 (但我不建议你这样)。最佳做法是您的解决方案。
【讨论】:
感谢您对 merege 的详细解释。从性能的角度来看,每次使用合并是否会对性能产生影响?此外,我正在考虑编写自己的注释来扩展@transactional,并且在调用任何带有注释的方法时应该调用一个方法,并且我将合并到该方法中,这样每个开发人员都不需要编写合并。这会是一个好的设计并且在技术上是可行的吗? 取决于场景,但性能可以忽略不计,你记得那总是一个 ORM。对于您的第二个问题,您可以使用像 Orika 或 Dozer 这样执行深层复制的 bean 映射器,但还有很多其他的。无论如何,很高兴为您提供帮助:)以上是关于将分离的实体合并到 JPA 中的实体管理器的最佳方法是啥的主要内容,如果未能解决你的问题,请参考以下文章