HHH-10728 - NullPointerException when using CriteriaBuilder.selectCase with CriteriaBuilder.equal

This commit is contained in:
DrBAXA 2017-03-27 09:43:55 +03:00 committed by Vlad Mihalcea
parent 2a9c0fe0dd
commit 19c03e0c5a
4 changed files with 116 additions and 24 deletions

View File

@ -33,7 +33,6 @@ import org.hibernate.query.criteria.internal.compile.RenderingContext;
public class SearchedCaseExpression<R>
extends ExpressionImpl<R>
implements Case<R>, Serializable {
private Class<R> javaType; // overrides the javaType kept on tuple-impl so that we can adjust it
private List<WhenClause> whenClauses = new ArrayList<WhenClause>();
private Expression<? extends R> otherwiseResult;
@ -59,7 +58,6 @@ public class SearchedCaseExpression<R>
CriteriaBuilderImpl criteriaBuilder,
Class<R> javaType) {
super( criteriaBuilder, javaType );
this.javaType = javaType;
}
public Case<R> when(Expression<Boolean> condition, R result) {
@ -77,24 +75,17 @@ public class SearchedCaseExpression<R>
public Case<R> when(Expression<Boolean> condition, Expression<? extends R> result) {
WhenClause whenClause = new WhenClause( condition, result );
whenClauses.add( whenClause );
adjustJavaType( result );
resetJavaType( result.getJavaType() );
return this;
}
@SuppressWarnings({"unchecked"})
private void adjustJavaType(Expression<? extends R> exp) {
if ( javaType == null ) {
javaType = (Class<R>) exp.getJavaType();
}
}
public Expression<R> otherwise(R result) {
return otherwise( buildLiteral( result ) );
}
public Expression<R> otherwise(Expression<? extends R> result) {
this.otherwiseResult = result;
adjustJavaType( result );
resetJavaType( result.getJavaType() );
return this;
}

View File

@ -32,7 +32,6 @@ import org.hibernate.query.criteria.internal.compile.RenderingContext;
public class SimpleCaseExpression<C,R>
extends ExpressionImpl<R>
implements SimpleCase<C,R>, Serializable {
private Class<R> javaType;
private final Expression<? extends C> expression;
private List<WhenClause> whenClauses = new ArrayList<WhenClause>();
private Expression<? extends R> otherwiseResult;
@ -61,7 +60,6 @@ public class SimpleCaseExpression<C,R>
Class<R> javaType,
Expression<? extends C> expression) {
super( criteriaBuilder, javaType);
this.javaType = javaType;
this.expression = expression;
}
@ -88,24 +86,17 @@ public class SimpleCaseExpression<C,R>
result
);
whenClauses.add( whenClause );
adjustJavaType( result );
resetJavaType( result.getJavaType() );
return this;
}
@SuppressWarnings({ "unchecked" })
private void adjustJavaType(Expression<? extends R> exp) {
if ( javaType == null ) {
javaType = (Class<R>) exp.getJavaType();
}
}
public Expression<R> otherwise(R result) {
return otherwise( buildLiteral(result) );
}
public Expression<R> otherwise(Expression<? extends R> result) {
this.otherwiseResult = result;
adjustJavaType( result );
resetJavaType( result.getJavaType() );
return this;
}

View File

@ -79,7 +79,7 @@ public class SelectCaseTest extends BaseEntityManagerFunctionalTestCase {
CriteriaQuery<Entity> query = cb.createQuery( Entity.class );
Root<Entity> 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<Entity> query = cb.createQuery( Entity.class );
Root<Entity> 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();
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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<Event> criteria = cb.createQuery(Event.class);
Root<Event> event = criteria.from(Event.class);
Path<EventType> type = event.get("type");
Expression<String> caseWhen = cb.<EventType, String>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<Event> resultList = session.createQuery(criteria).getResultList();
Assert.assertNotNull(resultList);
} );
}
@Test
public void testEqualClause() {
doInHibernate( this::sessionFactory, session -> {
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<Event> criteria = cb.createQuery(Event.class);
Root<Event> event = criteria.from(Event.class);
Path<EventType> type = event.get("type");
Expression<String> caseWhen = cb.<String>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<Event> 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
}
}