I want to build the having clause shown below using CriteriaBuilder
:
select objectid,
sum(case when attr_meta = 'severity' then 1 else 0 end) as severity,
sum(case when attr_meta = 'priority' then 1 else 0 end) as priority
from object d
group by objectid
having sum(case when attr_meta = 'severity' then 1 else 0 end) != 1
or sum(case when attr_meta = 'priority' then 1 else 0 end) != 1;
I tried the below approach:
Predicate p = cb.equal(cb.sum(cb.<Integer>selectCase()
.when(cb.equal(root.get("name"), 'severity'), 1).otherwise(0)), 1);
p = cb.or(p, cb.equal(cb.sum(cb.<Integer>selectCase()
.when(cb.equal(root.get("name"), 'priority'), 1).otherwise(0)), 1));
but this gives the below exception:
java.lang.NullPointerException
at java.lang.Class.isAssignableFrom(Native Method)
at org.hibernate.ejb.criteria.ValueHandlerFactory.isNumeric(ValueHandlerFactory.java:70)
at org.hibernate.ejb.criteria.predicate.ComparisonPredicate.<init>(ComparisonPredicate.java:69)
at org.hibernate.ejb.criteria.CriteriaBuilderImpl.equal(CriteriaBuilderImpl.java:392)
The exception seems to be coming from the outer CriteriaBuilderImpl.equal()
call, the one that encloses selectCase()
call.
The equal()
call internally needs type info of the Expression
. The selectCase()
call, while creating the Expression
, puts in type as null
. Do we have some way to handle this situation? Either a way to let the equal()
know the type, or a completely different approach to the above mentioned query?