java JPA remove()一个分离的实体:find()vs merge()-哪个更好?

jaxagkaj  于 2023-03-28  发布在  Java
关注(0)|答案(2)|浏览(89)

在删除分离实体的most examples中,remove通常与merge配对:

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

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

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

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

与使用merge相比,是否有性能优势?

6jjcrrmo

6jjcrrmo1#

为了使用EntityManager.remove(),你需要一个托管实体。如果你已经有了分离的实体,最简单的方法是调用merge()将它附加到持久化上下文。你可以使用find,但是因为分离的实体已经包含了必要的信息(class和id),所以没有必要显式地指定class和检索id。
如果你一开始就没有分离的实体,你只需要find()。所以在这种情况下使用find()并不是“更正确”,而是“更多的类型”。
如果你把“合并”看作是“更新”,这可能看起来很奇怪,但是当你把它看作是“重新附加”时就更有意义了,在这个例子中就是这样(JPA也是这么想的,你经常会看到“合并回持久化上下文”,这与“更新数据库中的实体”是不一样的,即使它可能会导致...除非例如remove()之后被调用)。

hts6caw3

hts6caw32#

我会说正确的方法是使用JPQL语句按ID删除实体,这样你就可以确保你的数据库只接收DELETE语句,而不是(浪费的)SELECT和DELETE。
我认为如果你想避免JPQL,你可以通过使用em.getReference而不是em.find(或merge)来达到同样的效果。
你真的应该检查生成的SQL语句。如果你看到一个select后面跟着一个delete语句,而你的逻辑不需要那个select,你的代码会比必要的慢得多。如果这种情况发生在一个循环中,它会非常慢。
如果你的算法在调用remove之前需要对其他实体属性做一些其他的事情,你仍然可以使用findmerge(不管是哪一个,它毕竟是一个SELECT语句),然后使用remove。在这种情况下,无论如何都没有更快的方法。

相关问题