diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLSerializer.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLSerializer.java index 7913b21e2..7fc02cb73 100644 --- a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLSerializer.java +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLSerializer.java @@ -329,40 +329,7 @@ public class JPQLSerializer extends SerializerBase { } public void visitLiteral(Object constant) { - if (constant instanceof Boolean) { - append(constant.toString()); - } else if (constant instanceof Number) { - append(constant.toString()); - } else if (constant instanceof String) { - append("'"); - append(escapeLiteral(constant.toString())); - append("'"); - } else if (constant instanceof Enum) { - append(constant.getClass().getName()); - append("."); - append(((Enum) constant).name()); - } else { - // TODO date time literals - throw new IllegalArgumentException("Unsupported constant " + constant); - } - } - - private String escapeLiteral(String str) { - StringBuilder builder = new StringBuilder(); - for (char ch : str.toCharArray()) { - if (ch == '\n') { - builder.append("\\n"); - continue; - } else if (ch == '\r') { - builder.append("\\r"); - continue; - } else if (ch == '\'') { - builder.append("''"); - continue; - } - builder.append(ch); - } - return builder.toString(); + append(templates.asLiteral(constant)); } @Override diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLTemplates.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLTemplates.java index b89e2dcc0..881c3e912 100644 --- a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLTemplates.java +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLTemplates.java @@ -190,4 +190,35 @@ public class JPQLTemplates extends Templates { return false; } + public String asLiteral(Object constant) { + if (constant instanceof Boolean) { + return constant.toString(); + } else if (constant instanceof Number) { + return constant.toString(); + } else if (constant instanceof String) { + return "'" + escapeLiteral(constant.toString()) + "'"; + } else if (constant instanceof Enum) { + return constant.getClass().getName() + "." + ((Enum) constant).name(); + } else { + return "'" + constant.toString() + "'"; + } + } + + private String escapeLiteral(String str) { + StringBuilder builder = new StringBuilder(); + for (char ch : str.toCharArray()) { + if (ch == '\n') { + builder.append("\\n"); + continue; + } else if (ch == '\r') { + builder.append("\\r"); + continue; + } else if (ch == '\'') { + builder.append("''"); + continue; + } + builder.append(ch); + } + return builder.toString(); + } } diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/AbstractJPATest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/AbstractJPATest.java index 3be0428b1..77f6e96f1 100644 --- a/querydsl-jpa/src/test/java/com/querydsl/jpa/AbstractJPATest.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/AbstractJPATest.java @@ -23,6 +23,9 @@ import java.util.*; import java.util.Calendar; import java.util.Map.Entry; +import org.joda.time.DateTime; +import org.joda.time.LocalDate; +import org.joda.time.LocalTime; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -311,6 +314,62 @@ public abstract class AbstractJPATest { assertEquals(ImmutableList.of(1L, 2L, 2L, 2L, 2L, 2L), query().from(cat).orderBy(cat.id.asc()) .select(cat.name.when("Bob123").then(1L).otherwise(2L)).fetch()); + List rv = query().from(cat).select(cat.name.when("Bob").then(1).otherwise(2)).fetch(); + assertInstancesOf(Integer.class, rv); + } + + @Test + @NoEclipseLink + @NoHibernate // https://hibernate.atlassian.net/browse/HHH-8653 + public void Case_Date() { + List rv = query().from(cat).select(cat.name.when("Bob").then(new LocalDate()) + .otherwise(new LocalDate().plusDays(1))).fetch(); + assertInstancesOf(LocalDate.class, rv); + } + + @Test + @NoHibernate // https://hibernate.atlassian.net/browse/HHH-8653 + @NoEclipseLink({MYSQL, POSTGRESQL}) + public void Case_Date2() { + List rv = query().from(cat).select(cat.name.when("Bob").then(new java.sql.Date(0)) + .otherwise(new java.sql.Date(0))).fetch(); + assertInstancesOf(java.sql.Date.class, rv); + } + + @Test + @NoEclipseLink + @NoHibernate // https://hibernate.atlassian.net/browse/HHH-8653 + public void Case_Time() { + List rv = query().from(cat).select(cat.name.when("Bob").then(new LocalTime()) + .otherwise(new LocalTime().plusHours(1))).fetch(); + assertInstancesOf(LocalTime.class, rv); + } + + @Test + @NoHibernate // https://hibernate.atlassian.net/browse/HHH-8653 + @NoEclipseLink({MYSQL, POSTGRESQL}) + public void Case_Time2() { + List rv = query().from(cat).select(cat.name.when("Bob").then(new java.sql.Time(0)) + .otherwise(new java.sql.Time(0))).fetch(); + assertInstancesOf(java.sql.Time.class, rv); + } + + @Test + @NoEclipseLink + @NoHibernate // https://hibernate.atlassian.net/browse/HHH-8653 + public void Case_Timestamp() { + List rv = query().from(cat).select(cat.name.when("Bob").then(new DateTime()) + .otherwise(new DateTime().plusHours(1))).fetch(); + assertInstancesOf(DateTime.class, rv); + } + + @Test + @NoHibernate // https://hibernate.atlassian.net/browse/HHH-8653 + @NoEclipseLink({MYSQL, POSTGRESQL}) + public void Case_Timestamp2() { + List rv = query().from(cat).select(cat.name.when("Bob").then(new java.sql.Timestamp(0)) + .otherwise(new java.sql.Timestamp(0))).fetch(); + assertInstancesOf(java.sql.Timestamp.class, rv); } @Test @@ -350,6 +409,12 @@ public abstract class AbstractJPATest { .select(cat.mate.when(savedCats.get(0)).then(0).otherwise(1)).fetch()); } + private static void assertInstancesOf(Class clazz, Iterable rows) { + for (T row : rows) { + assertEquals(row.toString(), clazz, row.getClass()); + } + } + @Test public void CaseBuilder() { QCat cat2 = new QCat("cat2");