Having an offer along with a “case when” at CriteriaBuilder

I want to build a 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 approach below:

 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 following 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 is like an external call to CriteriaBuilderImpl.equal() , which includes a call to selectCase() .

Calling equal() requires internal Expression type information. The call to selectCase() when creating Expression places the type as null . Do we have a way to deal with this situation? Any way to tell an equal() type or a completely different approach to the above query?

+6
source share
2 answers

Running typecast on an expression (using expression # as a (class) ) might help.

 Expression<Integer> sumExp = builder.sum( builder.<Integer>selectCase() .when(builder.equal(root.get("name"), "severity"), 1) .otherwise(0) ); Predicate eqPredicate = builder.equal(sumExp.as(Integer.class), 1); 
+5
source

I think the answer to this question should be to return cb.nullLiteral as the “other” part of the sentence. This is the solution that all this works for me. See the example below. If this helps, check this answer.

 cb.count(cb.selectCase().when( status.get("maxAction").in( introTypes ), 1).otherwise(cb.nullLiteral(Number.class)) ), 
+1
source

Source: https://habr.com/ru/post/946266/


All Articles