Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用SpringDataJPA发出一个修改查询,通过实体的ID删除一组实体?_Java_Spring_Jpa_Spring Data_Spring Data Jpa - Fatal编程技术网

Java 如何使用SpringDataJPA发出一个修改查询,通过实体的ID删除一组实体?

Java 如何使用SpringDataJPA发出一个修改查询,通过实体的ID删除一组实体?,java,spring,jpa,spring-data,spring-data-jpa,Java,Spring,Jpa,Spring Data,Spring Data Jpa,我正试图从数据库中删除大量记录。每个记录都有一个外键级联,当通过JPA一次删除一个记录时,每次删除大约需要5秒 因此,我决定编写一个JPQL查询,如下所示: @Repository public interface MyTableRepository extends JpaRepository<MyTable, Long> { @Query("delete from MyTable where id in :ids") void deleteAllIds(@Param

我正试图从数据库中删除大量记录。每个记录都有一个外键级联,当通过JPA一次删除一个记录时,每次删除大约需要5秒

因此,我决定编写一个JPQL查询,如下所示:

@Repository
public interface MyTableRepository extends JpaRepository<MyTable, Long> {
    @Query("delete from MyTable where id in :ids")
    void deleteAllIds(@Param("ids") Long[] ids);
}

如何实现我的目标?

您可能想编写一个单独的服务或类,您可以在其中编写一些原始sql。JPA确实允许您编写本机sql,但如果您打算这么做,您应该只编写一些原始sql并自己处理,确保删除该记录以及FK应用于的其他表中的任何关联记录。

要执行修改查询,需要使用
@modifying
注释该方法,如中所述

请注意,发出delete查询不会导致调用受影响实体的任何生命周期回调,因为该语句直接针对数据库执行。要获取调用的回调,请在给定标识符列表的情况下发出一个
findAll(…)
,并将结果导入
deleteAll(…)


如果您不管理上述任何层中的事务,请确保您还使用了
@Transactional
,以便查询执行按照JPA的要求在事务中运行。

您不能直接调用delete query。您必须返回父对象列表,遍历它们,调用session.delete(List.item.1)。然后在for循环外部刷新会话;myTableRepository.delete(objectsToDelete);我刚刚给你发了一个答案。检查一下。@WeareBorg-这显然是错误的。您当然可以直接发出删除命令。@Oliver下面的回答是正确的。您的
delete
方法缺少
@修改
。加上它,你就一切就绪了。谢谢,但是结构太复杂了,无法手动处理FK。所以,这对我来说不是一个解决方案。谢谢,这真的是一个非常有用和更干净的方法。你能给一些代码,说明问问题的用户是如何做到这一点的。。。我也有兴趣知道。答案准确地描述了需要做什么:向方法添加注释。参考的链接部分有一个例子。另外,
delete
方法必须用
@Transactional
注释。谢谢你,奥利弗,这完全解决了我的性能问题:在几秒钟内删除了70k个实体,其中包含了大约500k个链接实体。
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for DML operations [delete from com.lh.clte.domain.content.business.Hotel where id in (:ids_0_, :ids_1_, :ids_2_, :ids_3_, ... for the entire array size)]
    org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:293)
    org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:403)
    org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
    org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
    org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:111)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    com.sun.proxy.$Proxy72.deleteAllId(Unknown Source)