当前位置: 首页 > 知识库问答 >
问题:

JPQL到SQL使用Hibernate更新查询交叉连接问题

齐泰
2023-03-14

我有一个以下JPQL查询

update ObedCommand c set c.status = :newStatus, c.updatedAt = :updatedAt where c.procInfo.processId = :processId and c.status <> :oldStatus and (c.errorCode is null or c.errorCode not in :resultCodes)

用于转换为以下SQL查询

Hibernate: update eps.obed_command set status=?, updated_at=? where process_id=? and status<>? and (error_code is null or error_code not in  (?))

过去一切都是魅力。但后来我不得不升级一些依赖项版本,以匹配其他模块的依赖项。这时这个查询中断了,现在它被转换成了这个SQL。

Hibernate: update eps.obed_command cross join  set status=?, updated_at=? where process_id=? and status<>? and (error_code is null or error_code not in  (?))

正如你所料,这是行不通的。我得到以下错误

org.hibernate.exception.SQLGrammarException: could not execute statement
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not execute statement
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
    at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1614)
    at myapp.ObedCommandDAO.updateNotProcessedObedCommandToNewByProcessIdAndErrorCodeNotIn(ObedCommandDAO.java:142)
    at myapp.ObedCommandDAO$$FastClassBySpringCGLIB$$dacdb134.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:685)
    at myapp.ObedCommandDAO$$EnhancerBySpringCGLIB$$96300c8f.updateNotProcessedObedCommandToNewByProcessIdAndErrorCodeNotIn(<generated>)
    at myapp.ObedCommandDAOTest.lambda$updateNotProcessedObedCommandToNewByProcessIdAndErrorCodeNotInTest$1(ObedCommandDAOTest.java:258)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)
    at myapp.ObedCommandDAOTest.updateNotProcessedObedCommandToNewByProcessIdAndErrorCodeNotInTest(ObedCommandDAOTest.java:249)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
    at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:119)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
    at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.hibernate.exception.SQLGrammarException: could not execute statement
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:103)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200)
    at org.hibernate.hql.internal.ast.exec.BasicExecutor.doExecute(BasicExecutor.java:100)
    at org.hibernate.hql.internal.ast.exec.BasicExecutor.execute(BasicExecutor.java:59)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:454)
    at org.hibernate.engine.query.spi.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:377)
    at org.hibernate.internal.SessionImpl.executeUpdate(SessionImpl.java:1420)
    at org.hibernate.query.internal.AbstractProducedQuery.doExecuteUpdate(AbstractProducedQuery.java:1623)
    at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1605)
    ... 63 more
Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "cross"
  position: 25
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2497)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2233)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:310)
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:446)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:370)
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:149)
    at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:124)
    at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)
    at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)
    ... 70 more

我试图降低多个依赖项的级别,包括hibernate和spring数据jpa相关的依赖项,但没有起到任何作用。如果有人能帮我解决这个问题,我将不胜感激。

非常感谢。

共有1个答案

戴鸿羲
2023-03-14

也许你所经历的就是这样https://hibernate.atlassian.net/browse/HHH-13177

如果是这种情况,您应该将查询更改为

update ObedCommand AS c set c.status = :newStatus, c.updatedAt = :updatedAt where c.procInfo.processId = :processId and c.status <> :oldStatus and (c.errorCode is null or c.errorCode not in :resultCodes)

编辑尝试下一个使用子查询的方法

update ObedCommand AS c
set c.status    = :newStatus,
    c.updatedAt = :updatedAt
where c.procInfo.id in (select pi.id from ProcInfo pi where processId = :processId and c.procInfo.id = pi.id)
  and c.status <> :oldStatus
  and (c.errorCode is null or c.errorCode not in :resultCodes)

也许你必须将ProcInfo更改为正确的实体名称

 类似资料:
  • 问题内容: 给定开始日期和结束日期,我需要计算这两个日期之间的实例数。因此,给出以下内容: 桌子: 如果我在第一个(01/01)和第二个(02/01)之间看,我希望计数为2。如果我在寻找第3个到第4个,则期望计数为3。在整个日期范围内,那么我希望计数为4。有意义吗? 注意: 日期已转换为午夜,无需为此添加任何代码。此外,在整个问题中,日期均为dd / MM / yyyy格式。 目前,我有类似以下内

  • 首先,我将列出我在查询中使用的三个模型 产品实体: 合作伙伴实体: 和StockProductInfoEntity: 我想从数据库产品中获取所有股票的合作伙伴计算计数。为了方便起见,我创建了一个简单的DTO: 并在JPA存储库中编写JPQL查询: 但我的应用程序甚至没有启动,因为查询验证有问题。我收到以下消息: 原因:组织。冬眠QueryException:查询指定了联接提取,但提取的关联的所有者

  • 问题内容: 我必须更新一个值,该值由3个表的联接返回。 例子: 我想用其他在上述条件下加入的值来更新表的字段值。 如何在MS SQL Server中执行此操作? 问题答案: 为了清楚起见…该子句可以引用该子句中指定的表别名。所以在这种情况下是有效的 通用示例

  • 我尝试在pyspark中(在Spark 1.5.0上)运行以下SQL查询:

  • 本文向大家介绍Microsoft SQL Server 交叉连接,包括了Microsoft SQL Server 交叉连接的使用技巧和注意事项,需要的朋友参考一下 示例 A cross join是笛卡尔联接,表示两个表的笛卡尔乘积。此联接不需要任何条件即可联接两个表。左表中的每一行将连接到右表中的每一行。交叉联接的语法: 例: 结果: 请注意,还有其他方法可以应用CROSS JOIN。这是无条件的

  • 我在创建使用嵌套查询或使用联接更新实体CommitteeMembership的HQL时遇到问题,我首先尝试了以下查询: 但生成的SQL错误如下: 在“交叉连接”之后没有任何this使Hibernate抛出SQLGrammarException 之后,我将查询更改为使用子查询: 现在Hibernate投球 任何人都知道我如何在HQL中编写此更新查询??