在JPQL中表达式的情况

时间:2014-09-05 08:00:23

标签: hibernate jpa jpa-2.0 spring-data

当我用JPQL

实现'CASE WHEN'条件时,我遇到了问题
<dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.0-api</artifactId>
</dependency>


select u 
  from user u
  where u.languageId = case
  when :userLanguageId is null then :managerLanguageID
  else :userLanguageId 
   end

如果对应userLanguageId的数据为null,我想基于managerLanguageID获取数据。因此,当我使用THEN关键字的参数时会出现问题。但如果我手动设置参数,它可以正常工作:

select u 
  from user u
  where u.languageId = case
  when :userLanguageId is null then 1
  else :userLanguageId 
   end
不过,这是它抛出的例外:

  

引起:java.lang.IllegalArgumentException:   java.lang.ClassCastException:   org.hibernate.hql.internal.ast.tree.ParameterNode无法强制转换为   org.hibernate.hql.internal.ast.tree.SelectExpression at   org.springframework.data.jpa.repository.query.SimpleJpaQuery。(SimpleJpaQuery.java:73)     在   org.springframework.data.jpa.repository.query.SimpleJpaQuery.fromQueryAnnotation(SimpleJpaQuery.java:132)     在   org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy $ DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:114)

2 个答案:

答案 0 :(得分:1)

您的查询对我来说似乎不对:

select u 
from user u
where u.language_id = case
  when (u.languageId = :userLanguageId is null) then 1
  else :userLanguageId 
end

应该是:

select u 
from user u
where u.languageId = case
  when :userLanguageId is null then 1
  else :userLanguageId 
end

由于:

(1) u.languageId =  :userLanguageId is null 
(2) u.languageId = (:userLanguageId is null)
(3) <long> = <boolean>

表达式(1)等价于(2),(2)的类型是(3)的类型:你正在比较长整数和布尔值,我不认为Hibernate会接受它。 / p>

并且,因为coalesce存在:

select u 
from user u
where u.language_id = coalesce(:userLanguageId, 1)

答案 1 :(得分:1)

我明白了。我得到了解决方案。由于CaseNode.getDataType需要SelectExpression,因此发生了类异常。所以我们需要显式地转换动态参数(在整数或字符串中,无论我们需要什么数据类型)我们在查询中发送的内容。,........ CAST(:managerLanguageID为整数)

select u 
  from user u
  where u.languageId = case
  when :userLanguageId is null then CAST (:managerLanguageID as integer)
  else :userLanguageId 
   end