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;
|
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.Entity;
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
|
@ -13,22 +21,15 @@ import javax.persistence.Id;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.persistence.Tuple;
|
import javax.persistence.Tuple;
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
|
import javax.persistence.criteria.CriteriaBuilder.SimpleCase;
|
||||||
import javax.persistence.criteria.CriteriaQuery;
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
import javax.persistence.criteria.Expression;
|
import javax.persistence.criteria.Expression;
|
||||||
import javax.persistence.criteria.Path;
|
import javax.persistence.criteria.Path;
|
||||||
import javax.persistence.criteria.Root;
|
import javax.persistence.criteria.Root;
|
||||||
|
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.junit.Test;
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mote that these are simply performing syntax checking (can the criteria query
|
* Mote that these are simply performing syntax checking (can the criteria query
|
||||||
|
@ -40,7 +41,7 @@ public class BasicSimpleCaseTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
return new Class[] {Customer.class};
|
return new Class[] {Customer.class, TestEntity.class};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -209,6 +210,67 @@ public class BasicSimpleCaseTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
assertEquals( EmailType.UNKNOWN, results.get( 2 ).get( 1 ) );
|
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")
|
@Entity(name = "Customer")
|
||||||
@Table(name = "customer")
|
@Table(name = "customer")
|
||||||
public static class Customer {
|
public static class Customer {
|
||||||
|
@ -237,4 +299,72 @@ public class BasicSimpleCaseTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
public enum EmailType {
|
public enum EmailType {
|
||||||
LONG, NORMAL, UNKNOWN
|
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