java - 即使直接 SQL 查询有效,JPQL 也会抛出无法确定搜索的 case 语句的数据类型

标签 java hibernate jpa jpql

我正在尝试通过以下方式更新表格:

entityManager.createQuery(
        "UPDATE TestCaseExecutionDetailsEntity " +
        " SET status = " +
        " CASE WHEN (runOrder < :runOrder) THEN :completedStatus " +
        "      WHEN (runOrder = :runOrder) THEN :failedStatus " +
        "      WHEN (runOrder > :runOrder) THEN :abortedStatus " +
        " END " +
        " WHERE testExecutionJobId = :jobId")
    .setParameter("jobId", jobId)
    .setParameter("runOrder", runOrder)
    .setParameter("completedStatus", completed.name())
    .setParameter("failedStatus", failed.name())
    .setParameter("abortedStatus", aborted.name())
    .executeUpdate();

对于值 jobId = 1037runOrder = 2,它会抛出错误:

java.lang.IllegalArgumentException: org.hibernate.QueryException:
Could not determine data type for searched case statement
[update com.pkg.dataaccess.model.TestCaseExecutionDetailsEntity set status = CASE WHEN (runOrder < :runOrder) THEN :completedStatus WHEN (runOrder = :runOrder) THEN :failedStatus WHEN (runOrder > :runOrder) THEN :abortedStatus END WHERE testExecutionJobId = :jobId]

但是如果我尝试直接运行 SQL,它工作正常:

UPDATE TEST_CASE_EXECUTION_DETAILS tcxd
SET tcxd.STATUS =
CASE WHEN (tcxd.RUN_ORDER < 2) THEN 'completed'
WHEN (tcxd.RUN_ORDER = 2) THEN 'failed'
WHEN (tcxd.RUN_ORDER > 2) THEN 'aborted'
END
WHERE TEST_EXECUTION_JOB_ID = 1037;

我不知道为什么会发生这种情况。否则,我必须将逻辑放入代码库中,这可能会变得困惑。

完整堆栈跟踪 -

java.lang.IllegalArgumentException: org.hibernate.QueryException: Could not determine data type for searched case statement [update com.pkg.dataaccess.model.TestCaseExecutionDetailsEntity tcede  set tcede.status =  CASE WHEN (tcede.runOrder < :runOrder) THEN :completedStatus       WHEN (tcede.runOrder = :runOrder) THEN :failedStatus       WHEN (tcede.runOrder > :runOrder) THEN :abortedStatus  END  WHERE tcede.testExecutionJobId = :jobId]
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1679) ~[hibernate-entitymanager-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602) ~[hibernate-entitymanager-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608) ~[hibernate-entitymanager-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:294) ~[hibernate-entitymanager-5.1.0.Final.jar:5.1.0.Final]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_121]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_121]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_121]
        at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:347) ~[spring-orm-4.3.10.RELEASE.jar:4.3.10.RELEASE]
        at com.sun.proxy.$Proxy116.createQuery(Unknown Source) ~[?:?]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_121]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_121]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_121]
        at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298) ~[spring-orm-4.3.10.RELEASE.jar:4.3.10.RELEASE]
        at com.sun.proxy.$Proxy80.createQuery(Unknown Source) ~[?:?]
        at com.pkg.dataaccess.repository.TestDataAccessorRepository.updateCaseDetailsForFailedJob(TestRunsDataAccessorRepository.java:542) ~[classes/:?]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_121]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_121]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_121]
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) ~[spring-aop-4.3.10.RELEASE.jar:4.3.10.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) ~[spring-aop-4.3.10.RELEASE.jar:4.3.10.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.10.RELEASE.jar:4.3.10.RELEASE]
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.3.10.RELEASE.jar:4.3.10.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.10.RELEASE.jar:4.3.10.RELEASE]
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.10.RELEASE.jar:4.3.10.RELEASE]
        at com.sun.proxy.$Proxy83.updateCaseDetailsForFailedJob(Unknown Source) ~[?:?]
        at com.pkg.rest.controllers.EmailController.get(EmailController.java:51) ~[classes/:?]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_121]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_121]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_121]
        at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) ~[jersey-server-2.25.jar:?]
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144) ~[jersey-server-2.25.jar:?]
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161) ~[jersey-server-2.25.jar:?]
        at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160) ~[jersey-server-2.25.jar:?]
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) ~[jersey-server-2.25.jar:?]
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) ~[jersey-server-2.25.jar:?]
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) ~[jersey-server-2.25.jar:?]
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) ~[jersey-server-2.25.jar:?]
        at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326) [jersey-server-2.25.jar:?]
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) [jersey-common-2.25.jar:?]
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) [jersey-common-2.25.jar:?]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:315) [jersey-common-2.25.jar:?]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:297) [jersey-common-2.25.jar:?]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:267) [jersey-common-2.25.jar:?]
        at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) [jersey-common-2.25.jar:?]
        at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305) [jersey-server-2.25.jar:?]
        at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) [jersey-server-2.25.jar:?]
        at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473) [jersey-container-servlet-core-2.25.jar:?]
        at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427) [jersey-container-servlet-core-2.25.jar:?]
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388) [jersey-container-servlet-core-2.25.jar:?]
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341) [jersey-container-servlet-core-2.25.jar:?]
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228) [jersey-container-servlet-core-2.25.jar:?]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) [catalina.jar:8.0.41]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [catalina.jar:8.0.41]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-websocket.jar:8.0.41]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [catalina.jar:8.0.41]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [catalina.jar:8.0.41]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) [catalina.jar:8.0.41]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:94) [catalina.jar:8.0.41]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504) [catalina.jar:8.0.41]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) [catalina.jar:8.0.41]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [catalina.jar:8.0.41]
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620) [catalina.jar:8.0.41]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [catalina.jar:8.0.41]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:509) [catalina.jar:8.0.41]
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1104) [tomcat-coyote.jar:8.0.41]
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684) [tomcat-coyote.jar:8.0.41]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1524) [tomcat-coyote.jar:8.0.41]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1480) [tomcat-coyote.jar:8.0.41]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_121]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_121]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:8.0.41]
        at java.lang.Thread.run(Thread.java:745) [?:1.8.0_121]
Caused by: org.hibernate.QueryException: Could not determine data type for searched case statement [update com.pkg.dataaccess.model.TestCaseExecutionDetailsEntity tcede  set tcede.status =  CASE WHEN (tcede.runOrder < :runOrder) THEN :completedStatus       WHEN (tcede.runOrder = :runOrder) THEN :failedStatus       WHEN (tcede.runOrder > :runOrder) THEN :abortedStatus  END  WHERE tcede.testExecutionJobId = :jobId]
        at org.hibernate.QueryException.generateQueryException(QueryException.java:120) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:218) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:302) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:240) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1907) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:291) ~[hibernate-entitymanager-5.1.0.Final.jar:5.1.0.Final]
        ... 72 more
Caused by: org.hibernate.QueryException: Could not determine data type for searched case statement
        at org.hibernate.hql.internal.ast.tree.SearchedCaseNode.getDataType(SearchedCaseNode.java:62) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.hql.internal.ast.tree.BinaryLogicOperatorNode.extractDataType(BinaryLogicOperatorNode.java:239) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.hql.internal.ast.tree.BinaryLogicOperatorNode.initialize(BinaryLogicOperatorNode.java:49) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.hql.internal.ast.HqlSqlWalker.prepareLogicOperator(HqlSqlWalker.java:1369) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.hql.internal.ast.HqlSqlWalker.evaluateAssignment(HqlSqlWalker.java:1270) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.assignment(HqlSqlBaseWalker.java:1063) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.setClause(HqlSqlBaseWalker.java:763) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.updateStatement(HqlSqlBaseWalker.java:379) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:267) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:262) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:190) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:302) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:240) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1907) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:291) ~[hibernate-entitymanager-5.1.0.Final.jar:5.1.0.Final]
        ... 72 more

最佳答案

我在下面的查询中遇到了同样的问题。简单地在 CASE 语句中转换变量对我来说很有效:

SELECT SUM(
    CASE WHEN type = 'SOME_TYPE' THEN CAST(price AS float) ELSE CAST (-price AS FLOAT) END
)
FROM MyEntity;

关于java - 即使直接 SQL 查询有效,JPQL 也会抛出无法确定搜索的 case 语句的数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48903502/

相关文章:

java - 无法从 Lotus Notes 中的邮件获取 HTML 内容,即使在 setConvertMIME(false) 之后,getMIMEEntity() 也会返回 null

Hibernate @OneToOne 即使使用 @Fetch(FetchMode.JOIN) 也会执行多个查询

Java将json映射到两个对象

hibernate - jpa如何创建与父实体具有相同id的新实体(联合继承)

java - ArrayList 到 JTable

java - 将基于 Spring XML 的配置转换为基于 Java 的配置

java - Play 框架中出现 "groovy.lang.MissingFieldException: No such field: metaClass for class: java.lang.Class"错误

java - org.springframework.beans.factory.NoSuchBeanDefinitionException : No bean named 'transactionManager' is defined @Spring + JPA

java - 基于spring xml的bean定义, `bean`元素的类属性

java - 为什么我收到 HHH015011 : Unable to locate static metamodel field?