From c2d201fd9bbfba756d0ded24e5b839e9a3d65f15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Westk=C3=A4mper?= Date: Mon, 29 Sep 2014 23:06:23 +0300 Subject: [PATCH 1/2] Improve any path serialization --- .../mysema/query/jpa/AbstractJPASubQuery.java | 12 ++++---- .../query/jpa/JPACollectionAnyVisitor.java | 17 ++++------- .../com/mysema/query/jpa/JPQLSubQuery.java | 4 +++ .../jpa/JPACollectionAnyVisitorTest.java | 30 +++++++++---------- 4 files changed, 30 insertions(+), 33 deletions(-) diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/AbstractJPASubQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/AbstractJPASubQuery.java index 3050bcb5b..3b7491cab 100644 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/AbstractJPASubQuery.java +++ b/querydsl-jpa/src/main/java/com/mysema/query/jpa/AbstractJPASubQuery.java @@ -18,11 +18,8 @@ import com.mysema.query.JoinExpression; import com.mysema.query.JoinType; import com.mysema.query.QueryMetadata; import com.mysema.query.support.DetachableQuery; -import com.mysema.query.types.CollectionExpression; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.MapExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; +import com.mysema.query.support.Expressions; +import com.mysema.query.types.*; import com.mysema.query.types.query.NumberSubQuery; import com.mysema.query.types.template.NumberTemplate; @@ -70,6 +67,11 @@ public class AbstractJPASubQuery> extends Detac return queryMixin.from(o); } + @Override + public

Q from(CollectionExpression target, Path

alias) { + return queryMixin.fullJoin(Expressions.as((Path)target, alias)); + } + @Override @Deprecated public

Q fullJoin(CollectionExpression target) { diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPACollectionAnyVisitor.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPACollectionAnyVisitor.java index 812b51044..8e6a7cbfa 100644 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPACollectionAnyVisitor.java +++ b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPACollectionAnyVisitor.java @@ -13,21 +13,15 @@ */ package com.mysema.query.jpa; -import java.util.UUID; - import javax.persistence.Entity; +import java.util.UUID; import com.mysema.query.support.CollectionAnyVisitor; import com.mysema.query.support.Context; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.Ops; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.PredicateOperation; -import com.mysema.query.types.ToStringVisitor; +import com.mysema.query.types.*; import com.mysema.query.types.path.EntityPathBase; +import com.mysema.query.types.path.ListPath; +import com.mysema.query.types.path.SimplePath; /** * JPACollectionAnyVisitor extends the {@link CollectionAnyVisitor} class with module specific @@ -48,8 +42,7 @@ public final class JPACollectionAnyVisitor extends CollectionAnyVisitor { Path child = c.paths.get(i).getMetadata().getParent(); EntityPath replacement = (EntityPath) c.replacements.get(i); if (c.paths.get(i).getType().isAnnotationPresent(Entity.class)) { - query.from(replacement); - query.where(PredicateOperation.create(Ops.IN, replacement, child)); + query.from(new ListPath(c.paths.get(i).getType(), SimplePath.class, child.getMetadata()), replacement); } else { // join via parent Path parent = child.getMetadata().getParent(); diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLSubQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLSubQuery.java index a3032829a..34122e962 100644 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLSubQuery.java +++ b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLSubQuery.java @@ -14,6 +14,8 @@ package com.mysema.query.jpa; import com.mysema.query.Detachable; +import com.mysema.query.types.CollectionExpression; +import com.mysema.query.types.Path; /** * @author tiwe @@ -21,4 +23,6 @@ import com.mysema.query.Detachable; */ public interface JPQLSubQuery extends Detachable, JPACommonQuery{ +

JPQLSubQuery from(CollectionExpression target, Path

alias); + } diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPACollectionAnyVisitorTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPACollectionAnyVisitorTest.java index d2d149db3..d6d60535c 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPACollectionAnyVisitorTest.java +++ b/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPACollectionAnyVisitorTest.java @@ -13,10 +13,6 @@ */ package com.mysema.query.jpa; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - import com.mysema.query.jpa.domain.JobFunction; import com.mysema.query.jpa.domain.QCat; import com.mysema.query.jpa.domain.QDomesticCat; @@ -26,6 +22,8 @@ import com.mysema.query.types.ConstantImpl; import com.mysema.query.types.Expression; import com.mysema.query.types.Predicate; import com.mysema.query.types.TemplateExpressionImpl; +import org.junit.Test; +import static org.junit.Assert.assertTrue; public class JPACollectionAnyVisitorTest { @@ -46,8 +44,8 @@ public class JPACollectionAnyVisitorTest { public void Simple_BooleanOperation() { Predicate predicate = cat.kittens.any().name.eq("Ruth123"); assertMatches("exists \\(select 1\n" + - "from Cat cat_kittens.*\n" + - "where cat_kittens.* in elements\\(cat\\.kittens\\) and cat_kittens.*\\.name = \\?1\\)", serialize(predicate)); + "from cat.kittens as cat_kittens.*\n" + + "where cat_kittens.*\\.name = \\?1\\)", serialize(predicate)); } @Test @@ -64,18 +62,18 @@ public class JPACollectionAnyVisitorTest { public void Simple_StringOperation() { Predicate predicate = cat.kittens.any().name.substring(1).eq("uth123"); assertMatches("exists \\(select 1\n"+ - "from Cat cat_kittens.*\n" + - "where cat_kittens.* in elements\\(cat.kittens\\) and substring\\(cat_kittens.*\\.name,2\\) = \\?1\\)", serialize(predicate)); + "from cat.kittens as cat_kittens.*\n" + + "where substring\\(cat_kittens.*\\.name,2\\) = \\?1\\)", serialize(predicate)); } @Test public void And_Operation() { Predicate predicate = cat.kittens.any().name.eq("Ruth123").and(cat.kittens.any().bodyWeight.gt(10.0)); assertMatches("exists \\(select 1\n"+ - "from Cat cat_kittens.*\n" + - "where cat_kittens.* in elements\\(cat.kittens\\) and cat_kittens.*\\.name = \\?1\\) and exists \\(select 1\n" + - "from Cat cat_kittens.*\n" + - "where cat_kittens.* in elements\\(cat.kittens\\) and cat_kittens.*\\.bodyWeight > \\?2\\)", serialize(predicate)); + "from cat.kittens as cat_kittens.*\n" + + "where cat_kittens.*\\.name = \\?1\\) and exists \\(select 1\n" + + "from cat.kittens as cat_kittens.*\n" + + "where cat_kittens.*\\.bodyWeight > \\?2\\)", serialize(predicate)); } @Test @@ -83,8 +81,8 @@ public class JPACollectionAnyVisitorTest { Expression templateExpr = TemplateExpressionImpl.create(Boolean.class, "{0} = {1}", cat.kittens.any().name, ConstantImpl.create("Ruth123")); assertMatches("exists \\(select 1\n" + - "from Cat cat_kittens.*\n" + - "where cat_kittens.* in elements\\(cat\\.kittens\\) and cat_kittens.*\\.name = \\?1\\)", serialize(templateExpr)); + "from cat.kittens as cat_kittens.*\n" + + "where cat_kittens.*\\.name = \\?1\\)", serialize(templateExpr)); } @Test @@ -98,8 +96,8 @@ public class JPACollectionAnyVisitorTest { Predicate predicate = anyCat.name.eq("X"); assertMatches("exists \\(select 1\n" + - "from DomesticCat cat_kittens.*\n" + - "where cat_kittens.* in elements\\(cat.kittens\\) and cat_kittens.*\\.name = \\?1\\)", serialize(predicate)); + "from cat.kittens as cat_kittens.*\n" + + "where cat_kittens.*\\.name = \\?1\\)", serialize(predicate)); } private String serialize(Expression expression) { From 42e0310416a98fde18ca7939e53e01c70e29b59e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Westk=C3=A4mper?= Date: Tue, 30 Sep 2014 18:13:42 +0300 Subject: [PATCH 2/2] Fix exists rendering --- .../mysema/query/support/DetachableMixin.java | 31 +++++-------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/querydsl-core/src/main/java/com/mysema/query/support/DetachableMixin.java b/querydsl-core/src/main/java/com/mysema/query/support/DetachableMixin.java index f3f7bc86c..7f7dee1c6 100644 --- a/querydsl-core/src/main/java/com/mysema/query/support/DetachableMixin.java +++ b/querydsl-core/src/main/java/com/mysema/query/support/DetachableMixin.java @@ -18,28 +18,9 @@ import javax.annotation.Nullable; import com.mysema.query.Detachable; import com.mysema.query.QueryMetadata; import com.mysema.query.Tuple; -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.NullExpression; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.ProjectionRole; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.expr.ComparableExpression; -import com.mysema.query.types.expr.DateExpression; -import com.mysema.query.types.expr.DateTimeExpression; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.StringExpression; -import com.mysema.query.types.expr.TimeExpression; -import com.mysema.query.types.expr.Wildcard; -import com.mysema.query.types.query.BooleanSubQuery; -import com.mysema.query.types.query.ComparableSubQuery; -import com.mysema.query.types.query.DateSubQuery; -import com.mysema.query.types.query.DateTimeSubQuery; -import com.mysema.query.types.query.ListSubQuery; -import com.mysema.query.types.query.NumberSubQuery; -import com.mysema.query.types.query.SimpleSubQuery; -import com.mysema.query.types.query.StringSubQuery; -import com.mysema.query.types.query.TimeSubQuery; +import com.mysema.query.types.*; +import com.mysema.query.types.expr.*; +import com.mysema.query.types.query.*; /** * Mixin style implementation of the Detachable interface @@ -65,7 +46,11 @@ public class DetachableMixin implements Detachable { if (queryMixin.getMetadata().getJoins().isEmpty()) { throw new IllegalArgumentException("No sources given"); } - return unique(queryMixin.getMetadata().getJoins().get(0).getTarget()).exists(); + Expression expr = queryMixin.getMetadata().getJoins().get(0).getTarget(); + if (expr instanceof Operation && ((Operation)expr).getOperator() == Ops.ALIAS) { + expr = ((Operation)expr).getArg(1); + } + return unique(expr).exists(); } @Override