SFAH
SFAH

Reputation: 534

JPA: How to use CASE in SELECT Query

In the following query I want to select programs on the basis of the minimum and maximum age, but the point is it's not necessary that every program has minimum and maximum age, so I want to check in query if minimum or maximum age is present than check parameter 'age' that it should be lying between the minimum and maximum age

Query

@Query("Select p from Program p where (CASE WHEN p.minimumAge!=null AND p.maximumAge==null THEN p.minimumAge<=:age ELSE 0),(CASE WHEN p.minimumAge!=null AND p.maximumAge!=null THEN p.minimumAge<=:age AND p.maximumAge>=:age ELSE 0)")
List<Program> programs(@Param("age")int age);

Error

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: = near line 1, column 108 [Select p from com.ivl.MySportsAcademy.model.Program p where (CASE WHEN p.minimumAge!=null AND p.maximumAge==null THEN p.minimumAge<=:age ELSE 0),(CASE WHEN p.minimumAge!=null AND p.maximumAge!=null THEN p.minimumAge<=:age AND p.maximumAge>=:age ELSE 0)]
    at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:91) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:288) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:187) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:302) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:240) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1894) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:291) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    ... 48 common frames omitted

Upvotes: 1

Views: 1556

Answers (1)

beny23
beny23

Reputation: 35008

A couple of issues:

  • The error points you to column 108 which is p.maximumAge==null - there is no == in SQL, just =
  • You won't be able to use CASE WHEN THEN like an if statement to dynamically add/remove where clauses.

However, you should be able to use COALESCE to provide an alternative to null, so if you do:

Select p 
  from Program p 
 where COALESCE(p.maximumAge, :age) >= :age
   and COALESCE(p.minimumAge, :age) <= :age

Then whenever a program has a maximum age of NULL, the comparison is :age <= :age (which is always true). Same for the minimum.

Hope that helps

Upvotes: 2

Related Questions