在CriteriaBuilder中使用子句和'case when'

Nik*_*hil 6 java hibernate jpa criteria-api jpa-2.0

我想使用以下方法构建下面显示的having子句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;
Run Code Online (Sandbox Code Playgroud)

我尝试了以下方法:

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));
Run Code Online (Sandbox Code Playgroud)

但这给出了以下例外:

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)
Run Code Online (Sandbox Code Playgroud)

异常似乎来自外部CriteriaBuilderImpl.equal()呼叫,即selectCase()呼叫附带的外部呼叫.

equal()内部调用需要输入的信息Expression.的selectCase()通话,在创建Expression,放入类型null.我们有办法处理这种情况吗?要么equal()知道类型,要么采用与上述查询完全不同的方法?

Sna*_*ski 6

在表达式上执行类型转换(通过使用表达式#作为(类))可能会有所帮助.

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);
Run Code Online (Sandbox Code Playgroud)


Nic*_*arl 2

我认为这个问题的答案是让 cb.nullLiteral 返回 for 作为子句的“.otherwise”部分。这是让这一切对我有用的解决方案。请参阅下面的示例。如果这有帮助,请标记此答案。

cb.count(cb.selectCase().when( status.get("maxAction").in( introTypes ), 1).otherwise(cb.nullLiteral(Number.class)) ),  
Run Code Online (Sandbox Code Playgroud)