From 19c03e0c5a99900800a914c49f4cf046bf349388 Mon Sep 17 00:00:00 2001 From: DrBAXA Date: Mon, 27 Mar 2017 09:43:55 +0300 Subject: [PATCH] HHH-10728 - NullPointerException when using CriteriaBuilder.selectCase with CriteriaBuilder.equal --- .../expression/SearchedCaseExpression.java | 13 +-- .../expression/SimpleCaseExpression.java | 13 +-- .../criteria/selectcase/SelectCaseTest.java | 4 +- .../SearchedCaseExpressionTest.java | 110 ++++++++++++++++++ 4 files changed, 116 insertions(+), 24 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/query/criteria/internal/expression/SearchedCaseExpressionTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/SearchedCaseExpression.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/SearchedCaseExpression.java index 1a81bcec25..1a76dabeab 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/SearchedCaseExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/SearchedCaseExpression.java @@ -33,7 +33,6 @@ import org.hibernate.query.criteria.internal.compile.RenderingContext; public class SearchedCaseExpression extends ExpressionImpl implements Case, Serializable { - private Class javaType; // overrides the javaType kept on tuple-impl so that we can adjust it private List whenClauses = new ArrayList(); private Expression otherwiseResult; @@ -59,7 +58,6 @@ public class SearchedCaseExpression CriteriaBuilderImpl criteriaBuilder, Class javaType) { super( criteriaBuilder, javaType ); - this.javaType = javaType; } public Case when(Expression condition, R result) { @@ -77,24 +75,17 @@ public class SearchedCaseExpression public Case when(Expression condition, Expression result) { WhenClause whenClause = new WhenClause( condition, result ); whenClauses.add( whenClause ); - adjustJavaType( result ); + resetJavaType( result.getJavaType() ); return this; } - @SuppressWarnings({"unchecked"}) - private void adjustJavaType(Expression exp) { - if ( javaType == null ) { - javaType = (Class) exp.getJavaType(); - } - } - public Expression otherwise(R result) { return otherwise( buildLiteral( result ) ); } public Expression otherwise(Expression result) { this.otherwiseResult = result; - adjustJavaType( result ); + resetJavaType( result.getJavaType() ); return this; } diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/SimpleCaseExpression.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/SimpleCaseExpression.java index c941bf889b..2c4d3049db 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/SimpleCaseExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/SimpleCaseExpression.java @@ -32,7 +32,6 @@ import org.hibernate.query.criteria.internal.compile.RenderingContext; public class SimpleCaseExpression extends ExpressionImpl implements SimpleCase, Serializable { - private Class javaType; private final Expression expression; private List whenClauses = new ArrayList(); private Expression otherwiseResult; @@ -61,7 +60,6 @@ public class SimpleCaseExpression Class javaType, Expression expression) { super( criteriaBuilder, javaType); - this.javaType = javaType; this.expression = expression; } @@ -88,24 +86,17 @@ public class SimpleCaseExpression result ); whenClauses.add( whenClause ); - adjustJavaType( result ); + resetJavaType( result.getJavaType() ); return this; } - @SuppressWarnings({ "unchecked" }) - private void adjustJavaType(Expression exp) { - if ( javaType == null ) { - javaType = (Class) exp.getJavaType(); - } - } - public Expression otherwise(R result) { return otherwise( buildLiteral(result) ); } public Expression otherwise(Expression result) { this.otherwiseResult = result; - adjustJavaType( result ); + resetJavaType( result.getJavaType() ); return this; } diff --git a/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/selectcase/SelectCaseTest.java b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/selectcase/SelectCaseTest.java index 19943b8503..f89eaa16a0 100644 --- a/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/selectcase/SelectCaseTest.java +++ b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/selectcase/SelectCaseTest.java @@ -79,7 +79,7 @@ public class SelectCaseTest extends BaseEntityManagerFunctionalTestCase { CriteriaQuery query = cb.createQuery( Entity.class ); Root from = query.from( Entity.class ); - query.select( from ).where( cb.equal( from.get( "value" ), selectCase.as( String.class ) ) ); + query.select( from ).where( cb.equal( from.get( "value" ).as( String.class ), selectCase.as( String.class ) ) ); entityManager.createQuery( query ).getResultList(); } @@ -113,7 +113,7 @@ public class SelectCaseTest extends BaseEntityManagerFunctionalTestCase { CriteriaQuery query = cb.createQuery( Entity.class ); Root from = query.from( Entity.class ); - query.select( from ).where( cb.equal( from.get( "value" ), selectCase.as( String.class ) ) ); + query.select( from ).where( cb.equal( from.get( "value" ).as( String.class ), selectCase.as( String.class ) ) ); entityManager.createQuery( query ).getResultList(); } diff --git a/hibernate-core/src/test/java/org/hibernate/query/criteria/internal/expression/SearchedCaseExpressionTest.java b/hibernate-core/src/test/java/org/hibernate/query/criteria/internal/expression/SearchedCaseExpressionTest.java new file mode 100644 index 0000000000..b89bfacbd7 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/query/criteria/internal/expression/SearchedCaseExpressionTest.java @@ -0,0 +1,110 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.query.criteria.internal.expression; + +import java.util.List; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Expression; +import javax.persistence.criteria.Path; +import javax.persistence.criteria.Root; + +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Assert; +import org.junit.Test; + +import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; + +/** + * + * @author Vasyl Danyliuk + */ +public class SearchedCaseExpressionTest extends BaseCoreFunctionalTestCase { + + @Test + public void testCaseClause() { + doInHibernate( this::sessionFactory, session -> { + CriteriaBuilder cb = session.getCriteriaBuilder(); + + CriteriaQuery criteria = cb.createQuery(Event.class); + + Root event = criteria.from(Event.class); + Path type = event.get("type"); + + Expression caseWhen = cb.selectCase(type) + .when(EventType.TYPE1, "Admin Event") + .when(EventType.TYPE2, "User Event") + .when(EventType.TYPE3, "Reporter Event") + .otherwise(""); + + criteria.select(event); + criteria.where(cb.equal(caseWhen, "Admin Event")); // OK when use cb.like() method and others + List resultList = session.createQuery(criteria).getResultList(); + + Assert.assertNotNull(resultList); + } ); + } + + @Test + public void testEqualClause() { + doInHibernate( this::sessionFactory, session -> { + CriteriaBuilder cb = session.getCriteriaBuilder(); + + CriteriaQuery criteria = cb.createQuery(Event.class); + + Root event = criteria.from(Event.class); + Path type = event.get("type"); + + Expression caseWhen = cb.selectCase() + .when(cb.equal(type, EventType.TYPE1), "Type1") + .otherwise(""); + + criteria.select(event); + criteria.where(cb.equal(caseWhen, "Admin Event")); // OK when use cb.like() method and others + List resultList = session.createQuery(criteria).getResultList(); + + + Assert.assertNotNull(resultList); + } ); + } + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[]{Event.class, EventType.class}; + } + + @Entity(name = "Event") + public static class Event { + + @Id + private Long id; + + @Column + private EventType type; + + protected Event() { + } + + public EventType getType() { + return type; + } + + public Event type(EventType type) { + this.type = type; + return this; + } + } + + public enum EventType { + + TYPE1, TYPE2, TYPE3 + + } +} \ No newline at end of file