Hibernate Criteria API throws NullPointerException from SearchedCaseExpression when building a CASE expression


#1

hi,

I am using hibernate as a JPA implementation to run selectcase and groupby in the same criteria api query. Unfortunately it is giving me a nullpointerexception which I don’t understand why. Below is a shorter version of the real query for the sake of simplicity:

	CriteriaBuilder builder = em.getCriteriaBuilder();

	CriteriaQuery<Tuple> criteria = builder.createTupleQuery();

	Root<ProductItem> pi = criteria.from(ProductItem.class);
	
	Join<ProductItem, Ereturn> er = pi.join("ereturn", JoinType.LEFT);
	Join<ProductItem, User> shipper = er.join("shipper", JoinType.LEFT);
	Join<ProductItem, User> carrier = er.join("carrier", JoinType.LEFT);
	Join<ProductItem, User> consignee = er.join("consignee", JoinType.LEFT);
	Join<ProductItem, User> destination = er.join("destination", JoinType.LEFT);
	Join<ProductItem, ProductDefinition> pd = pi.join("product", JoinType.LEFT);
	Join<ProductItem, Receptacle> receptacle = pi.join("receptacle", JoinType.LEFT);
	Join<Receptacle, MasterCrossDock> mcd = receptacle.join("masterCrossDock", JoinType.LEFT);

	criteria.select( 
			builder.tuple(
					er.get("id").alias("er_id"), er.get("globalId").alias("globalId"), er.get("rma").alias("rma"), er.get("trackingNumber").alias("trackingNumber"), er.get("invoice").alias("invoice")
					, builder.selectCase()
						.when(pi.get("scanDateTime").isNull(), "item to arrive")
						.when(pi.get("scanDateTime").isNotNull(), "received")
						.when(mcd.get("dispatchDate").isNotNull(), "in transit")
						.when(mcd.get("completionDate").isNotNull(), "completed")
						.alias("ereturn_status")
					, er.get("carrier").get("id").alias("carrier_id"), er.get("carrier").get("firstName").alias("carrier_fn")
					, er.get("shipper").get("id").alias("shipper_id"), er.get("shipper").get("firstName").alias("shipper_fn")
					, er.get("consignee").get("id").alias("consignee_id"), er.get("consignee").get("firstName").alias("consignee_fn"), er.get("consignee").get("lastName").alias("consignee_ln")
					, builder.count(pi.get("id")).alias("num_products")
					, pi.get("receptacle").get("id").alias("r_id"), pi.get("receptacle").get("closed").alias("closed")
					, mcd.get("id").alias("mcd_id"), mcd.get("dispatchDate").alias("dispatchDate"), mcd.get("completionDate").alias("completionDate")
					)
			);
	
	criteria.groupBy(er.get("id"), er.get("globalId"), er.get("rma"), er.get("trackingNumber"), er.get("invoice")
			, builder.selectCase()
			.when(pi.get("scanDateTime").isNull(), "item to arrive")
			.when(pi.get("scanDateTime").isNotNull(), "received")
			.when(mcd.get("dispatchDate").isNotNull(), "in transit")
			.when(mcd.get("completionDate").isNotNull(), "completed"));

	TypedQuery<Tuple> q = em.createQuery( criteria );
	
	if (first >= 0 && window > 0) {
		q.setFirstResult(first).setMaxResults(window);
	}
			
	List<Tuple> tuples = q.getResultList();

And this is the error I am getting (java.lang.NullPointerException) which does not explain anything to me:

SEVERE: Servlet.service() for servlet [jersey-servlet] in context with path [/returnitRest] threw exception [java.lang.NullPointerException] with root cause
java.lang.NullPointerException
	at org.hibernate.query.criteria.internal.expression.SearchedCaseExpression.lambda$renderProjection$1(SearchedCaseExpression.java:118)
	at org.hibernate.query.criteria.internal.expression.SearchedCaseExpression.render(SearchedCaseExpression.java:141)
	at org.hibernate.query.criteria.internal.expression.SearchedCaseExpression.renderProjection(SearchedCaseExpression.java:116)
	at org.hibernate.query.criteria.internal.expression.CompoundSelectionImpl.render(CompoundSelectionImpl.java:83)
	at org.hibernate.query.criteria.internal.Renderable.renderProjection(Renderable.java:34)
	at org.hibernate.query.criteria.internal.QueryStructure.render(QueryStructure.java:241)
	at org.hibernate.query.criteria.internal.CriteriaQueryImpl.interpret(CriteriaQueryImpl.java:292)
	at org.hibernate.query.criteria.internal.compile.CriteriaCompiler.compile(CriteriaCompiler.java:149)
	at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:3655)
	at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:204)
	at returnitRest.EreturnDAO.fetchEreturns(EreturnDAO.java:1283)
	at returnitRest.EreturnResource.filterEreturn(EreturnResource.java:557)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
...

Any thoughts?


#2
java.lang.NullPointerException
	at org.hibernate.query.criteria.internal.expression.SearchedCaseExpression.lambda$renderProjection$1(SearchedCaseExpression.java:118)

If you check the line 118 in SearchedCaseExpression, you will find this:

caseStatement
.append( " else " )
.append( ( (Renderable) getOtherwiseResult() ).render( renderingContext ) )
.append( " end" );

I created the HHH-13167 Jira issue and provided a fix for this. Hopefully, it will be included in 5.4.1.