【问题标题】:JPA remove() a deteched entity: find() vs merge() - Which is better?JPA remove() 一个 deteched 实体:find() 与 merge() - 哪个更好?
【发布时间】:2021-03-17 20:37:12
【问题描述】:

most examples的删除分离实体中,删除通常与合并配对:

em.remove(em.merge(detachedEntity));

我的问题是为什么使用 find 不是“更正确”:

em.remove(em.find(Entity.class, detachedEntity.id));

em.remove(em.find(detachedEntity.getClass(), detachedEntity.id));

与使用合并相比有性能优势吗?

【问题讨论】:

    标签: java jpa


    【解决方案1】:

    为了使用EntityManager.remove(),您需要一个托管实体。如果您已经拥有分离的实体,最简单的方法是调用merge() 将其附加到持久性上下文。您可以使用find,但由于分离的实体已经包含必要的信息(类和 id),因此无需显式指定类并检索 id。

    如果你一开始没有分离实体,你只需要find()。所以在这种情况下使用find() 并不是“更正确”,而是“输入更多”。

    如果您将“合并”视为“更新”,这可能看起来很奇怪,但当您将其视为“重新附加”时会更有意义(在这种情况下)(JPA 也是这样认为的,您经常看到“合并回持久化上下文”的措辞,这与“更新数据库中的实体”不同,即使它可能导致……除非之后调用 remove()

    【讨论】:

      【解决方案2】:

      我会说正确的方法是 JPQL 语句按 ID 删除实体,这样您将确保您的数据库将仅接收 DELETE 语句而不是(浪费的)SELECT 后跟 DELETE。

      如果想避免 JPQL,我认为您可以通过使用 em.getReference 而不是 em.find(或合并)来达到相同的效果。

      您确实应该检查生成的 SQL 语句。如果您看到一个选择后跟一个删除语句,并且您的逻辑不需要该选择,那么您的代码将比必要的慢得多。如果这发生在一个循环中,它将会非常缓慢。

      如果您的算法需要对其他实体属性执行其他操作,您仍然可以使用findmerge(不管是哪一个,毕竟这将是一个SELECT 语句),然后是remove在调用删除之前。在这种情况下,无论如何都没有更快的方法。

      【讨论】:

      • 虽然您不应该将em.remove() 用于批量删除,但单个删除对性能的影响可能有点夸大了。我也在考虑getReference(),您可以使用它来避免选择,但使用additional caveats
      猜你喜欢
      • 2010-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-07
      • 2014-04-02
      • 2013-11-28
      • 2010-10-11
      • 2013-09-10
      相关资源
      最近更新 更多