HHH-13199 Add test case
This commit is contained in:
parent
e2510d9e3d
commit
9c72384e1f
|
@ -6,6 +6,14 @@
|
|||
*/
|
||||
package org.hibernate.jpa.test.criteria.simplecase;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Convert;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.GeneratedValue;
|
||||
|
@ -13,22 +21,15 @@ import javax.persistence.Id;
|
|||
import javax.persistence.Table;
|
||||
import javax.persistence.Tuple;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaBuilder.SimpleCase;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Expression;
|
||||
import javax.persistence.criteria.Path;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
||||
import static javax.persistence.criteria.CriteriaBuilder.SimpleCase;
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Mote that these are simply performing syntax checking (can the criteria query
|
||||
|
@ -40,7 +41,7 @@ public class BasicSimpleCaseTest extends BaseEntityManagerFunctionalTestCase {
|
|||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] {Customer.class};
|
||||
return new Class[] {Customer.class, TestEntity.class};
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -209,6 +210,67 @@ public class BasicSimpleCaseTest extends BaseEntityManagerFunctionalTestCase {
|
|||
assertEquals( EmailType.UNKNOWN, results.get( 2 ).get( 1 ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-13199")
|
||||
public void testCaseEnumInSum() throws Exception {
|
||||
doInJPA( this::entityManagerFactory, em -> {
|
||||
// create entities
|
||||
TestEntity e1 = new TestEntity();
|
||||
e1.setEnumField( TestEnum.VAL_1 );
|
||||
e1.setValue( 20L );
|
||||
em.persist( e1 );
|
||||
|
||||
TestEntity e2 = new TestEntity();
|
||||
e2.setEnumField( TestEnum.VAL_2 );
|
||||
e2.setValue( 10L );
|
||||
em.persist( e2 );
|
||||
} );
|
||||
|
||||
doInJPA( this::entityManagerFactory, em -> {
|
||||
// Works in previous version (e.g. Hibernate 5.3.7.Final)
|
||||
// Fails in Hibernate 5.4.0.Final
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<Tuple> query = cb.createTupleQuery();
|
||||
Root<TestEntity> r = query.from( TestEntity.class );
|
||||
|
||||
CriteriaBuilder.Case<Long> case1 = cb.selectCase();
|
||||
case1.when( cb.equal( r.<TestEnum> get( "enumField" ), cb.literal( TestEnum.VAL_1 ) ),
|
||||
r.<Long> get( "value" ) );
|
||||
case1.otherwise( cb.nullLiteral( Long.class ) );
|
||||
|
||||
CriteriaBuilder.Case<Long> case2 = cb.selectCase();
|
||||
case2.when( cb.equal( r.<TestEnum> get( "enumField" ), cb.literal( TestEnum.VAL_2 ) ),
|
||||
r.<Long> get( "value" ) );
|
||||
case2.otherwise( cb.nullLiteral( Long.class ) );
|
||||
|
||||
/*
|
||||
* Forces enums to be bound as parameters, so SQL is something like
|
||||
* "SELECT enumfield AS enumField, SUM(CASE WHEN enumfield = ? THEN value
|
||||
* ELSE NULL END) AS VAL_1, SUM(CASE WHEN enumfield =? THEN value ELSE NULL END) AS VAL_1 FROM TestEntity
|
||||
* GROUP BY enumfield"
|
||||
*/
|
||||
query
|
||||
.select( cb.tuple( r.<TestEnum> get( "enumField" ).alias( "enumField" ),
|
||||
cb.sum( case1 ).alias( "VAL_1" ),
|
||||
cb.sum( case2 ).alias( "VAL_2" ) ) )
|
||||
.groupBy( r.<TestEnum> get( "enumField" ) );
|
||||
|
||||
List<Tuple> list = em.createQuery( query ).getResultList();
|
||||
assertEquals( 2, list.size() );
|
||||
for ( Tuple tuple : list ) {
|
||||
TestEnum enumVal = tuple.get( "enumField", TestEnum.class );
|
||||
if ( enumVal == TestEnum.VAL_1 ) {
|
||||
assertEquals( 20L, tuple.get( "VAL_1", Long.class ).longValue() );
|
||||
assertNull( tuple.get( "VAL_2", Long.class ) );
|
||||
}
|
||||
else if ( enumVal == TestEnum.VAL_2 ) {
|
||||
assertNull( tuple.get( "VAL_1", Long.class ) );
|
||||
assertEquals( 10L, tuple.get( "VAL_2", Long.class ).longValue() );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
@Entity(name = "Customer")
|
||||
@Table(name = "customer")
|
||||
public static class Customer {
|
||||
|
@ -237,4 +299,72 @@ public class BasicSimpleCaseTest extends BaseEntityManagerFunctionalTestCase {
|
|||
public enum EmailType {
|
||||
LONG, NORMAL, UNKNOWN
|
||||
}
|
||||
|
||||
@Entity(name = "TestEntity")
|
||||
public static class TestEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private long id;
|
||||
|
||||
@Convert(converter = TestEnumConverter.class)
|
||||
private TestEnum enumField;
|
||||
|
||||
private Long value;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public TestEnum getEnumField() {
|
||||
return enumField;
|
||||
}
|
||||
|
||||
public void setEnumField(TestEnum enumField) {
|
||||
this.enumField = enumField;
|
||||
}
|
||||
|
||||
public Long getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Long value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static enum TestEnum {
|
||||
VAL_1("1"),
|
||||
VAL_2("2");
|
||||
|
||||
private final String value;
|
||||
|
||||
private TestEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static TestEnum fromValue(String value) {
|
||||
if (value.equals(VAL_1.value)) {
|
||||
return VAL_1;
|
||||
} else if (value.equals(VAL_2.value)) {
|
||||
return VAL_2;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestEnumConverter implements AttributeConverter<TestEnum, String> {
|
||||
@Override
|
||||
public String convertToDatabaseColumn(TestEnum attribute) {
|
||||
return attribute == null ? null : attribute.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestEnum convertToEntityAttribute(String dbData) {
|
||||
return dbData == null ? null : TestEnum.fromValue(dbData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue