当前位置: 首页 > 知识库问答 >
问题:

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

杜海
2023-03-14

我正在使用JPA Spring开发Web应用程序。我的项目层结构是web-

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

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

有没有其他更好的方法来做到这一点。有什么设计模式可用吗?

共有1个答案

米夕
2023-03-14

我认为这是最好的方法。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);

合并操作允许将状态从分离的实体传播到由 EntityManager 管理的持久性实体。

应用于实体X的合并操作的语义学如下:

  • 如果X是分离的实体,则将X的状态复制到具有相同标识的预先存在的托管实体实例X'上,或者创建X的新托管副本X'
  • 如果X是新的实体实例,则创建新的受管实体实例X’,并将X的状态复制到新的受管理实体实例X’
  • 如果X是已删除的实体实例,则合并操作将引发<code>IllegalArgumentException(否则事务提交将失败)
  • 如果X是托管实体,则合并操作将忽略该实体,但是,如果这些关系已用级联元素值<code>cascade=merge
  • 对于由具有级联元素值<code>cascade=MERGE
  • 如果X是一个合并到X'的实体,并且引用了另一个实体Y,其中未指定<code>cascade=MERGE

持久性提供程序不能合并标记为LAZY且尚未提取的字段:它必须在合并时忽略此类字段。

实体使用的任何版本列必须在合并操作期间和/或刷新或提交时由持久性运行时实现检查。在缺少<code>Version</code>列的情况下,持久性提供程序运行时在合并操作期间不会执行其他版本检查。

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

 类似资料:
  • 问题内容: 当业务层创建一个新的实体时,该实体在逻辑上表示应该更新的现有实体的实例(例如,它们共享相同的业务密钥),这是合并不良做法的方法吗? 我问是因为在分离的实体上显式设置ID对我来说很奇怪,但是即使User实体的equals和hashcode方法得到了适当实现,在这里设置ID是确保合并发生的唯一方法。 有更好的做法吗? 此方法是否有特定的缺点,以后会困扰我? 谢谢参观! 问题答案: 该代码将

  • 问题内容: 我有三个JPA实体类,并具有以下层次结构: 那是: 使用Spring Data JPA,为此类实体编写存储库类的最佳方法是什么? 我知道我可以写这些: 但是,如果在类中有一个字段,我在: 我还要在其他两个存储库中编写这种方法,这有点烦人。是否有更好的方法来处理这种情况? 我想知道的另一点是应该是只读存储库(即扩展类),而其他两个存储库应公开所有CRUD操作。 让我知道可能的解决方案。

  • null 我能找到的使用JPA/Hibernate的唯一有效解决方案是执行以下步骤。这是因为hibernate将实体保留在第一级缓存中,直到事务结束。 创建新实体 强制快速刷新() 分离实体 这样做的开销是 null 使用JDBC或JdbcTemplate,但您必须为实体编写自己的插入 所以问题是:是否存在同时坚持和分离的可能性,或者甚至更好地坚持而不成为被管理的?

  • 问题内容: “独立实体”是什么意思?在交易期间如何将托管实体转换为独立实体? 问题答案: 分离实体是状态不能由JPA提供程序反映的实体。 换句话说,如果您更改其状态(即通过setter方法),则这些更改将不会保存到基础数据库中,因为JPA提供程序不必“观察”此类实体。 如果实体E1是受管实体,则可以使其分离调用(非常合理的命名)方法。您还可以使用它将清除整个PersistenceContext并有

  • 我知道我可以写这些: 但是,如果在类中有一个字段,并且我在: 我也必须在其他两个存储库中编写这样的方法,这有点烦人…有没有更好的方法来处理这种情况? 我想指出的另一点是,应该是一个只读存储库(即扩展类),而另外两个存储库应该公开所有CRUD操作。 让我知道可能的解决办法。

  • 另外,我有一个IOC托管bean,它内部有一个事务方法。 有2个实体具有单向Many2One-- AuModule在上没有引用