We're updating the issue view to help you get more done. 

NullPointerException when using CriteriaBuilder.selectCase with CriteriaBuilder.equal

Description

Sample code:

1 2 3 4 5 6 7 8 9 10 11 12 13 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, builder.equal(selectCase, true)); query.where(predicate);

It find that CriteriaBuilder.equal will throws NullPointerException, below is the stacktrace

1 2 3 4 5 6 7 8 9 10 11 12 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

After checking the source code, it suspected that there is a bug in

1 org.hibernate.jpa.criteria.expression.SearchedCaseExpression

cause the selectCase.getJavaType() always return null.

The javaType override logic of SearchedCaseExpression actually do nothing:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 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; }

I think it should call AbstractTupleElement.resetJavaType instead of adjustJavaType

Environment

None

Status

Assignee

Unassigned

Reporter

raykou

Fix versions

backPortable

None

Suitable for new contributors

Yes, likely

Requires Release Note

None

backportDecision

None

Components

Affects versions

5.1.0
4.3.11

Priority

Major