mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-30 21:08:30 +08:00
Serialize constants in case constructs as literals for Hibernate
This commit is contained in:
parent
9a8500ce42
commit
41b73ea816
@ -141,4 +141,9 @@ public class HQLTemplates extends JPQLTemplates {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCaseWithLiterals() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -79,6 +79,8 @@ public class JPQLSerializer extends SerializerBase<JPQLSerializer> {
|
||||
|
||||
private boolean inProjection = false;
|
||||
|
||||
private boolean inCaseOperation = false;
|
||||
|
||||
static{
|
||||
joinTypes.put(JoinType.DEFAULT, COMMA);
|
||||
joinTypes.put(JoinType.FULLJOIN, "\n full join ");
|
||||
@ -279,23 +281,64 @@ public class JPQLSerializer extends SerializerBase<JPQLSerializer> {
|
||||
|
||||
@Override
|
||||
public void visitConstant(Object constant) {
|
||||
boolean wrap = templates.wrapConstant(constant);
|
||||
if (wrap) {
|
||||
append("(");
|
||||
}
|
||||
append("?");
|
||||
if (!getConstantToLabel().containsKey(constant)) {
|
||||
final String constLabel = String.valueOf(getConstantToLabel().size()+1);
|
||||
getConstantToLabel().put(constant, constLabel);
|
||||
append(constLabel);
|
||||
if (inCaseOperation && templates.isCaseWithLiterals()) {
|
||||
visitLiteral(constant);
|
||||
} else {
|
||||
append(getConstantToLabel().get(constant));
|
||||
boolean wrap = templates.wrapConstant(constant);
|
||||
if (wrap) {
|
||||
append("(");
|
||||
}
|
||||
append("?");
|
||||
if (!getConstantToLabel().containsKey(constant)) {
|
||||
final String constLabel = String.valueOf(getConstantToLabel().size()+1);
|
||||
getConstantToLabel().put(constant, constLabel);
|
||||
append(constLabel);
|
||||
} else {
|
||||
append(getConstantToLabel().get(constant));
|
||||
}
|
||||
if (wrap) {
|
||||
append(")");
|
||||
}
|
||||
}
|
||||
if (wrap) {
|
||||
append(")");
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(ParamExpression<?> param, Void context) {
|
||||
append("?");
|
||||
@ -336,7 +379,9 @@ public class JPQLSerializer extends SerializerBase<JPQLSerializer> {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void visitOperation(Class<?> type, Operator<?> operator, List<? extends Expression<?>> args) {
|
||||
boolean old = wrapElements;
|
||||
boolean oldInCaseOperation = inCaseOperation;
|
||||
inCaseOperation = inCaseOperation || operator.equals(Ops.CASE) || operator.equals(Ops.CASE_EQ);
|
||||
boolean oldWrapElements = wrapElements;
|
||||
wrapElements = templates.wrapElements(operator);
|
||||
|
||||
if (operator == Ops.EQ && args.get(1) instanceof Operation &&
|
||||
@ -387,7 +432,8 @@ public class JPQLSerializer extends SerializerBase<JPQLSerializer> {
|
||||
super.visitOperation(type, operator, args);
|
||||
}
|
||||
|
||||
wrapElements = old;
|
||||
inCaseOperation = oldInCaseOperation;
|
||||
wrapElements = oldWrapElements;
|
||||
}
|
||||
|
||||
private void visitNumCast(List<? extends Expression<?>> args) {
|
||||
|
||||
@ -183,4 +183,8 @@ public class JPQLTemplates extends Templates {
|
||||
return queryHandler;
|
||||
}
|
||||
|
||||
public boolean isCaseWithLiterals() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -303,19 +303,11 @@ public abstract class AbstractJPATest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@NoHibernate // https://hibernate.atlassian.net/browse/HHH-4700
|
||||
@NoBatooJPA
|
||||
public void Case() {
|
||||
query().from(cat).list(cat.name.when("Bob").then(1).otherwise(2));
|
||||
}
|
||||
|
||||
@Test(expected=ClassCastException.class)
|
||||
@NoEclipseLink
|
||||
@NoBatooJPA
|
||||
public void Case_Hibernate() {
|
||||
query().from(cat).list(cat.name.when("Bob").then(1).otherwise(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Case2() {
|
||||
query().from(cat)
|
||||
|
||||
@ -19,6 +19,7 @@ import com.mysema.query.DefaultQueryMetadata;
|
||||
import com.mysema.query.JoinType;
|
||||
import com.mysema.query.QueryMetadata;
|
||||
import com.mysema.query.domain.QCat;
|
||||
import com.mysema.query.jpa.domain.JobFunction;
|
||||
import com.mysema.query.jpa.domain.Location;
|
||||
import com.mysema.query.jpa.domain.QDomesticCat;
|
||||
import com.mysema.query.jpa.domain.QEmployee;
|
||||
@ -223,4 +224,32 @@ public class JPQLSerializerTest {
|
||||
assertEquals("select cat_\nfrom Cat cat_\n inner join cat_.mate on cat_.mate.alive",
|
||||
serializer.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void visitLiteral_boolean() {
|
||||
JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT);
|
||||
serializer.visitLiteral(Boolean.TRUE);
|
||||
assertEquals("true", serializer.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void visitLiteral_number() {
|
||||
JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT);
|
||||
serializer.visitLiteral(1.543);
|
||||
assertEquals("1.543", serializer.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void visitLiteral_string() {
|
||||
JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT);
|
||||
serializer.visitLiteral("abc''def");
|
||||
assertEquals("'abc''''def'", serializer.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void visitLiteral_enum() {
|
||||
JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT);
|
||||
serializer.visitLiteral(JobFunction.MANAGER);
|
||||
assertEquals("com.mysema.query.jpa.domain.JobFunction.MANAGER", serializer.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user