首页 文章

什么是在JPA中将分离的实体合并到实体管理器的最佳方法

提问于
浏览
3

我正在使用JPA spring开发Web应用程序 . 我的项目层结构是web - > service - > DAO - > GenericDAO . 所有类都被实例化为singleton spring bean . GenericDAO使用@PersistenceContext注入entityManager实例 .

我的应用程序在http会话中获取存储中的域实体 . 在对这些实体执行任何db操作之前,需要使用merge将其重新附加到实体管理器 . 我想知道将实体合并到实体管理器的最佳方法 . 目前每次调用事务方法时,我都调用genericDAO.merge(object) . 例如

@Transactional
public void addProducts() {
   Order order = getOrderFromHttpSession();
   genericDAO.merge(order);
   // delete existing products
   // add new products
   // other db operations.
}

有没有其他更好的方法来做到这一点 . 有没有任何设计模式?

1 回答

  • 3

    我认为这是最好的方式 . 出于这个原因,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是一个托管实体,则合并操作会忽略它,但是,如果这些关系已使用级联元素值cascade = MERGE或cascade = ALL注释进行注释,则合并操作将级联到由X关系引用的实体 . 对于具有级联元素值cascade = MERGE或cascade = ALL的X的关系所引用的所有实体Y,Y被递归地合并为Y' . 对于由X引用的所有这样的Y,X'被设置为引用Y' . (注意,如果管理X,则X与X'是同一个对象 . )如果X是合并到X'的实体,并且引用另一个实体Y,其中未指定cascade = MERGE或cascade = ALL,则导航来自X'的相同关联产生对具有与Y相同的持久标识的托管对象Y'的引用 . 持久性提供者不能合并尚未提取的标记为LAZY的字段:它必须在合并时忽略这些字段 . 在合并操作期间和/或刷新或提交时,必须由持久性运行时实现检查实体使用的任何Version列 . 如果没有Version列,则在合并操作期间,持久性提供程序运行时不会执行其他版本检查 .

    另一种方法是em.find(someKey)并复制每个已更改的信息 . (但我不建议你这样做) . 最佳实践是您的解决方案 .

相关问题