From dc0b362b8cd61854068068567f60d271e487f94a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Westk=C3=A4mper?= Date: Fri, 14 Feb 2014 22:23:25 +0200 Subject: [PATCH] Improve join creation #666 --- .../com/mysema/query/domain/p9/Article.java | 14 ++++++ .../com/mysema/query/domain/p9/Content.java | 10 ++++ .../com/mysema/query/domain/p9/Person.java | 9 ++++ .../com/mysema/query/jpa/JPAQueryMixin.java | 20 ++++++++ .../mysema/query/jpa/JPAQueryMixinTest.java | 48 +++++++++++++++++++ 5 files changed, 101 insertions(+) create mode 100644 querydsl-apt/src/test/java/com/mysema/query/domain/p9/Article.java create mode 100644 querydsl-apt/src/test/java/com/mysema/query/domain/p9/Content.java create mode 100644 querydsl-apt/src/test/java/com/mysema/query/domain/p9/Person.java diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Article.java b/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Article.java new file mode 100644 index 000000000..d8b9384e9 --- /dev/null +++ b/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Article.java @@ -0,0 +1,14 @@ +package com.mysema.query.domain.p9; + +import javax.persistence.Entity; + +@Entity +public class Article { + + String name; + + Content content; + + Person author; + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Content.java b/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Content.java new file mode 100644 index 000000000..ed9a566a0 --- /dev/null +++ b/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Content.java @@ -0,0 +1,10 @@ +package com.mysema.query.domain.p9; + +import javax.persistence.Embeddable; + +@Embeddable +public class Content { + + Article article; + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Person.java b/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Person.java new file mode 100644 index 000000000..1c05c44e2 --- /dev/null +++ b/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Person.java @@ -0,0 +1,9 @@ +package com.mysema.query.domain.p9; + +import javax.persistence.Entity; + +@Entity +public class Person { + + String firstName, lastName; +} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPAQueryMixin.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPAQueryMixin.java index 36cd5e100..a4b07b0e2 100644 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPAQueryMixin.java +++ b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPAQueryMixin.java @@ -16,6 +16,8 @@ package com.mysema.query.jpa; import java.util.Map; import java.util.Set; +import javax.persistence.Entity; + import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.mysema.query.JoinFlag; @@ -34,6 +36,7 @@ import com.mysema.query.types.PathImpl; import com.mysema.query.types.PathMetadata; import com.mysema.query.types.PathType; import com.mysema.query.types.Predicate; +import com.mysema.query.types.path.CollectionPathBase; /** * JPAQueryMixin extends {@link QueryMixin} to support JPQL join construction @@ -78,6 +81,15 @@ public class JPAQueryMixin extends QueryMixin { return super.createAlias(expr, alias); } + private boolean isEntityPath(Path path) { + if (path instanceof CollectionPathBase) { + return isEntityPath((Path) ((CollectionPathBase)path).any()); + } else { + return path instanceof EntityPath + || path.getType().isAnnotationPresent(Entity.class); + } + } + private Class getElementTypeOrType(Path path) { if (path instanceof CollectionExpression) { return ((CollectionExpression)path).getParameter(0); @@ -94,6 +106,14 @@ public class JPAQueryMixin extends QueryMixin { return (Path) aliases.get(path); } else if (metadata.getPathType() == PathType.COLLECTION_ANY) { return (Path) shorten(metadata.getParent()); + } else if (!isEntityPath(path)) { + Path parent = shorten(metadata.getParent()); + if (parent.equals(metadata.getParent())) { + return path; + } else { + return new PathImpl(path.getType(), + new PathMetadata(parent, metadata.getElement(), metadata.getPathType())); + } } else if (metadata.getParent().getMetadata().isRoot()) { Class type = getElementTypeOrType(path); Path newPath = new PathImpl(type, path.toString().replace('.', '_')); diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAQueryMixinTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAQueryMixinTest.java index 82380d9b5..e8eb6aff5 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAQueryMixinTest.java +++ b/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAQueryMixinTest.java @@ -9,9 +9,13 @@ import org.junit.Test; import com.mysema.query.JoinExpression; import com.mysema.query.JoinType; import com.mysema.query.QueryMetadata; +import com.mysema.query.domain.p9.QArticle; import com.mysema.query.jpa.domain.QCat; +import com.mysema.query.jpa.domain4.QBookMark; +import com.mysema.query.jpa.domain4.QBookVersion; import com.mysema.query.types.PathMetadataFactory; import com.mysema.query.types.Predicate; +import com.mysema.query.types.path.StringPath; public class JPAQueryMixinTest { @@ -108,4 +112,48 @@ public class JPAQueryMixinTest { assertEquals(Arrays.asList(cat_kittens.name.asc()), md.getOrderBy()); } + + @Test + public void OrderBy_Embeddable() { + QBookVersion bookVersion = QBookVersion.bookVersion; + mixin.from(bookVersion); + mixin.orderBy(bookVersion.definition.name.asc()); + + QueryMetadata md = mixin.getMetadata(); + assertEquals(Arrays.asList(new JoinExpression(JoinType.DEFAULT, bookVersion)), + md.getJoins()); + assertEquals(Arrays.asList(bookVersion.definition.name.asc()), + md.getOrderBy()); + } + + @Test + public void OrderBy_Embeddable2() { + QArticle article = QArticle.article; + QArticle article_content_article = new QArticle("article_content_article"); + mixin.from(article); + mixin.orderBy(article.content.article.name.asc()); + + QueryMetadata md = mixin.getMetadata(); + assertEquals(Arrays.asList( + new JoinExpression(JoinType.DEFAULT, article), + new JoinExpression(JoinType.LEFTJOIN, article.content.article.as(article_content_article))), + md.getJoins()); + assertEquals(Arrays.asList(article_content_article.name.asc()), + md.getOrderBy()); + } + + @Test + public void OrderBy_Embeddable_Colllection() { + QBookVersion bookVersion = QBookVersion.bookVersion; + QBookMark bookMark = new QBookMark("bookVersion_definition_bookMarks"); + mixin.from(bookVersion); + mixin.orderBy(bookVersion.definition.bookMarks.any().comment.asc()); + + QueryMetadata md = mixin.getMetadata(); + assertEquals(Arrays.asList(new JoinExpression(JoinType.DEFAULT, bookVersion)), + md.getJoins()); + assertEquals(Arrays.asList(new StringPath(bookVersion.definition.bookMarks, "comment").asc()), + md.getOrderBy()); + + } }