java jpa中批量删除的最佳实践是什么

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29104609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 14:42:02  来源:igfitidea点击:

What is best practice for bulk delete in jpa

javajpaeclipselinkjpa-2.1

提问by user902383

I'm trying to do bulk delete in my entities, i thought best solution will be to go with CriteriaDelete. But CriteriaDeletedoes not cascade (at least not for me).

我正在尝试在我的实体中进行批量删除,我认为最好的解决方案是使用CriteriaDelete. 但CriteriaDelete不会级联(至少对我来说不是)。

So seems like only solution which i have is to do select first, and delete each element seperately. Which does not seems wrong to me.

所以似乎我唯一的解决方案是先选择,然后单独删除每个元素。这对我来说似乎没有错。

Is anyone have better idea how to do bulk delete? Is it actually better way?

有没有人有更好的主意如何进行批量删除?它实际上是更好的方法吗?

If it helps I'm using eclipselink 2.5.2.

如果有帮助,我将使用 eclipselink 2.5.2。

回答by Chris

The options are:

选项是:

  1. use the cascade.Remove setting on the mapping, loading entities and calling em.remove on each
  2. Use bulk delete on the main entity and have the "ON DELETE CASCADE" database option set so that the database will cascade the delete for you. EclipseLink has a @CascadeOnDelete annotation that lets it know the "ON DELETE CASCADE" is set on a relationship, or to create it if using JPA for DDL generation: http://eclipse.org/eclipselink/documentation/2.5/jpa/extensions/a_cascadeondelete.htm
  3. Use multiple bulk deletes to remove children that might be referenced before removing the main entity. For example: "Delete FROM Child c where c.parent = (select p from Parent P where [delete-conditions])" and "Delete FROM Parent p where [delete-conditions]" See section 10.2.4 of http://docs.oracle.com/middleware/1212/toplink/OTLCG/queries.htm#OTLCG94370for details.
  1. 在映射上使用cascade.Remove 设置,加载实体并在每个实体上调用em.remove
  2. 在主实体上使用批量删除并设置“ON DELETE CASCADE”数据库选项,以便数据库为您级联删除。EclipseLink 有一个 @CascadeOnDelete 注释,让它知道在关系上设置了“ON DELETE CASCADE”,或者如果使用 JPA 生成 DDL 则创建它:http: //eclipse.org/eclipselink/documentation/2.5/jpa/extensions /a_cascadeondelete.htm
  3. 在删除主实体之前,使用多次批量删除来删除可能被引用的子项。例如:“Delete FROM Child c where c.parent = (select p from Parent P where [delete-conditions])”和“Delete FROM Parent p where [delete-conditions]”见http://的10.2.4节docs.oracle.com/middleware/1212/toplink/OTLCG/queries.htm#OTLCG94370了解详情。

回答by Arkantos

If you really care about the time it takes to perform this bulk delete, I suggest you use JPQL to delete your entities. When you issue a DELETEJPQL query, it will directly issue a delete on those entities without retrieving them in the first place.

如果您真的关心执行此批量删除所需的时间,我建议您使用 JPQL 删除您的实体。当您发出DELETEJPQL 查询时,它将直接对这些实体发出删除操作,而不会首先检索它们。

int deletedCount = entityManager.createQuery("DELETE FROM Country").executeUpdate(); 

You can even do conditional deletes based on some parameters on those entities using Query API like below

您甚至可以使用 Query API 根据这些实体的某些参数进行条件删除,如下所示

Query query = entityManager.createQuery("DELETE FROM Country c 
                              WHERE c.population < :p");
int deletedCount = query.setParameter(p, 100000).executeUpdate();

executeUpdatewill return the number of deleted rows once the operation is complete.

executeUpdate操作完成后将返回删除的行数。

If you've proper cascading type in place in your entities like CascadeType.ALL(or) CascadeType.REMOVE, then the above query will do the trick for you.

如果您的实体CascadeType.ALL(如(or) )中有适当的级联类型CascadeType.REMOVE,则上述查询将为您解决问题。

@Entity
class Employee {

    @OneToOne(cascade=CascadeType.REMOVE)
    private Address address;

}

For more details, have a look at thisand this.

有关更多详细信息,请查看thisthis

回答by Neil Stockton

JPQL BULK DELETE(whether using string-based JPQL or using Criteria JPQL) is not intended to cascade (i.e follow the cascade type settings for fields). If you want cascading then you either set up the datastore to use real FOREIGN KEYs, or you pull back the objects to delete and call EntityManager.remove().

JPQL BULK DELETE(无论是使用基于字符串的 JPQL 还是使用 Criteria JPQL)并不是为了级联(即遵循字段的级联类型设置)。如果您想要级联,那么您要么将数据存储设置为使用 real FOREIGN KEYs,要么拉回对象以删除并调用EntityManager.remove().