Sample code: {code:java} Set<Long> depts = new HashSet<>(); ... Case<Boolean> selectCase = builder.selectCase(); selectCase.otherwise(false); selectCase.when( builder.and( builder.equal(join.get("actionPartyType"), ActionPartyType.DEPARTMENT), join.get("actionPartyId").in(depts) ), true); ... predicate = builder.and(predicate, {color:red} builder.equal(selectCase, true) {color} ); query.where(predicate); {code}
It find that CriteriaBuilder.equal will throws NullPointerException, below is the stacktrace
{code:java} Caused by: java.lang.NullPointerException at java.lang.Class.isAssignableFrom(Native Method) at org.hibernate.jpa.criteria.ValueHandlerFactory.isNumeric(ValueHandlerFactory.java:52) at org.hibernate.jpa.criteria.predicate.ComparisonPredicate.<init>(ComparisonPredicate.java:52) at org.hibernate.jpa.criteria.CriteriaBuilderImpl.equal(CriteriaBuilderImpl.java:367) at com.xxx.business.dao.wf.impl.ProcessInstanceDAOImpl$1.prepareQuery(ProcessInstanceDAOImpl.java:116) at com.xxx.business.dao.wf.impl.ProcessInstanceDAOImpl$1.prepareQuery(ProcessInstanceDAOImpl.java:1) at com.xxx.business.searching.CriteriaQuerySearch.executeGetRowsCount(CriteriaQuerySearch.java:78) at com.xxx.business.searching.Search$2.call(Search.java:124) at com.xxx.business.searching.Search$2.call(Search.java:1) at com.xxx.business.dao.impl.DataAccessSupportImpl.executeWithTransaction(DataAccessSupportImpl.java:224) ... 166 more {code}
After checking the source code, it suspected that there is a bug in {code:java} org.hibernate.jpa.criteria.expression.SearchedCaseExpression {code} cause the selectCase.getJavaType() always return null.
The javaType override logic of SearchedCaseExpression actually do nothing:
{code:java} private Class<R> javaType; // overrides the javaType kept on tuple-impl so that we can adjust it
...
public Case<R> when(Expression<Boolean> condition, Expression<? extends R> result) { WhenClause whenClause = new WhenClause( condition, result ); whenClauses.add( whenClause ); adjustJavaType( result ); return this; }
@SuppressWarnings({"unchecked"}) private void adjustJavaType(Expression<? extends R> exp) { if ( javaType == null ) { javaType = (Class<R>) exp.getJavaType(); } }
...
public Expression<R> otherwise(Expression<? extends R> result) { this.otherwiseResult = result; adjustJavaType( result ); return this; } {code}
I think it should call AbstractTupleElement.resetJavaType instead of adjustJavaType |
|