【问题标题】:Deleting records with order by, limit in Spring hibernate throws InvalidDataAccessResourceUsageException在 Spring hibernate 中使用 order by、limit 删除记录抛出 InvalidDataAccessResourceUsageException
【发布时间】:2021-03-26 10:09:44
【问题描述】:

我想删除 MySQL 表中的数百万行,如果我尝试一次全部删除它们,则会出现 SQLException - Connection is closed 异常,因此按照this StackOverflow answer 中的建议决定删除它们分成较小的块,但我用这个 JPA 原生查询得到了 Spring InvalidDataAccessResourceUsageException

@Modifying
@Query(nativeQuery = true, value = "delete from customer where user_id = :userId ORDER BY id limit :limit")
int deleteByUserIdWithLimit(int userId, int limit);

如果我在上面的查询中删除 ORDER BY id 就可以了。 Spring JPA 对这些类型的查询有什么限制吗?

这是堆栈跟踪:

org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [delete from customer where user_id = ? ORDER BY id limit ?]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:281)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:154)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:149)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.sun.proxy.$Proxy96.deleteByUserIdWithLimit(Unknown Source)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:205)
    at com.sun.proxy.$Proxy84.deleteByUserIdWithLimit(Unknown Source)
    at io.deletion.listener.repository.RepositoryTest.apiHistoryRepoTest(RepositoryTest.java:61)
    ... 50 more
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "DELETE FROM CUSTOMER WHERE USER_ID = ? ORDER[*] BY ID LIMIT ?"; SQL statement: delete from customer where user_id = ? ORDER BY id limit ? [42000-200]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:453)
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
    at org.h2.message.DbException.get(DbException.java:205)
    at org.h2.message.DbException.get(DbException.java:181)
    at org.h2.message.DbException.getSyntaxError(DbException.java:229)
    at org.h2.command.Parser.getSyntaxError(Parser.java:1051)
    at org.h2.command.Parser.prepareCommand(Parser.java:741)
    at org.h2.engine.Session.prepareLocal(Session.java:657)
    at org.h2.engine.Session.prepareCommand(Session.java:595)
    at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1235)
    at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:76)
    at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:352)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$1.doPrepare(StatementPreparerImpl.java:90)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:176)
    ... 95 more
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "DELETE FROM CUSTOMER WHERE USER_ID = ? ORDER[*] BY ID LIMIT ?"; SQL statement: delete from customer where user_id = ? ORDER BY id limit ? [42000-200]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:453)
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
    at org.h2.message.DbException.get(DbException.java:205)
    at org.h2.message.DbException.get(DbException.java:181)
    at org.h2.message.DbException.getSyntaxError(DbException.java:229)
    at org.h2.command.Parser.getSyntaxError(Parser.java:1051)
    at org.h2.command.Parser.prepareCommand(Parser.java:741)
    at org.h2.engine.Session.prepareLocal(Session.java:657)
    at org.h2.engine.Session.prepareCommand(Session.java:595)
    at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1235)
    at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:76)
    at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:352)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$1.doPrepare(StatementPreparerImpl.java:90)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:176)
    ... 95 more

【问题讨论】:

  • 删除 SQL 语句中的 order by 子句没有意义。
  • @kingGarfield 没有 ORDER BY 记录删除不会是确定性的;不这样做会产生奇怪的影响(包括在某些情况下破坏复制)

标签: java mysql spring hibernate jpa


【解决方案1】:

您正在尝试在 h2 数据库中执行 mySql 查询。 h2 不支持按顺序删除。尝试使用 mysql 数据库。

【讨论】:

  • 感谢您指出。在查询数据库之前,我认为异常来自 spring 框架本身
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-06
  • 2011-09-15
  • 2020-11-19
  • 2013-09-20
  • 2014-09-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多