我想使用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;
我尝试了以下方法:
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));
但是这给出了以下例外:
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)
异常似乎来自外部CriteriaBuilderImpl.equal()
来电,即selectCase()
来电。{/ p>
equal()
调用内部需要Expression
的类型信息。在创建selectCase()
时,Expression
调用会将类型设置为null
。我们有办法处理这种情况吗?是让equal()
知道类型的方法,还是对上述查询采用完全不同的方法?
答案 0 :(得分:6)
在表达式上执行类型转换(使用Expression#as(Class))可能有所帮助。
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);
答案 1 :(得分:1)
我认为对此的答案是将cb.nullLiteral返回为该子句的“.otherwise”部分。这个解决方案让所有这些对我有用。见下面的例子。如果这有帮助,请标记这个答案。
cb.count(cb.selectCase().when( status.get("maxAction").in( introTypes ), 1).otherwise(cb.nullLiteral(Number.class)) ),