From 3f2ca5ccaddf243229081094aa31d3a470243fcc Mon Sep 17 00:00:00 2001 From: Ruben Dijkstra Date: Thu, 4 Dec 2014 19:52:17 +0100 Subject: [PATCH 1/3] Respect the user-specified existing templates during JPAQuery.clone() --- .../mysema/query/jpa/impl/AbstractJPAQuery.java | 17 ++++++++++++++++- .../com/mysema/query/jpa/impl/JPAQuery.java | 10 ++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/AbstractJPAQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/AbstractJPAQuery.java index b8cf89514..05e63be05 100644 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/AbstractJPAQuery.java +++ b/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/AbstractJPAQuery.java @@ -355,13 +355,28 @@ public abstract class AbstractJPAQuery> extends JP */ public abstract Q clone(EntityManager entityManager); + /** + * Clone the state of this query to a new instance with the given EntityManager + * using the specified templates + * + * @param entityManager + * @param templates + * @return + */ + public abstract Q clone(EntityManager entityManager, JPQLTemplates templates); + /** * Clone the state of this query to a new instance * * @return */ public Q clone() { - return this.clone(this.entityManager); + JPQLTemplates existingTemplates = getTemplates(); + if (existingTemplates != null) { + return clone(entityManager, existingTemplates); + }else { + return clone(entityManager); + } } } diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAQuery.java index 534b3a8c2..645f62f54 100644 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAQuery.java +++ b/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAQuery.java @@ -74,10 +74,16 @@ public class JPAQuery extends AbstractJPAQuery { super(em, templates, metadata); } - public JPAQuery clone(EntityManager entityManager) { - JPAQuery q = new JPAQuery(entityManager, JPAProvider.getTemplates(entityManager), getMetadata().clone()); + @Override + public JPAQuery clone(EntityManager entityManager, JPQLTemplates templates) { + JPAQuery q = new JPAQuery(entityManager, templates, getMetadata().clone()); q.clone(this); return q; } + @Override + public JPAQuery clone(EntityManager entityManager) { + return clone(entityManager, JPAProvider.getTemplates(entityManager)); + } + } From 9c093a4d61c607938b343f5213639488d3bc693a Mon Sep 17 00:00:00 2001 From: Ruben Dijkstra Date: Thu, 4 Dec 2014 21:14:14 +0100 Subject: [PATCH 2/3] Change clone() to copy all state --- .../java/com/mysema/query/jpa/impl/AbstractJPAQuery.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/AbstractJPAQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/AbstractJPAQuery.java index 05e63be05..399ce304e 100644 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/AbstractJPAQuery.java +++ b/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/AbstractJPAQuery.java @@ -357,7 +357,7 @@ public abstract class AbstractJPAQuery> extends JP /** * Clone the state of this query to a new instance with the given EntityManager - * using the specified templates + * and the specified templates * * @param entityManager * @param templates @@ -371,12 +371,7 @@ public abstract class AbstractJPAQuery> extends JP * @return */ public Q clone() { - JPQLTemplates existingTemplates = getTemplates(); - if (existingTemplates != null) { - return clone(entityManager, existingTemplates); - }else { - return clone(entityManager); - } + return clone(entityManager, getTemplates()); } } From 4ecba55bc848abee10de33b5319cf8d78508846b Mon Sep 17 00:00:00 2001 From: Ruben Dijkstra Date: Wed, 17 Dec 2014 23:04:10 +0100 Subject: [PATCH 3/3] Implement the JPAQueryMutabilityTests --- .../mysema/query/JPAQueryMutabilityTest.java | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/querydsl-jpa/src/test/java/com/mysema/query/JPAQueryMutabilityTest.java b/querydsl-jpa/src/test/java/com/mysema/query/JPAQueryMutabilityTest.java index 3fcde62f5..a042dd639 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/JPAQueryMutabilityTest.java +++ b/querydsl-jpa/src/test/java/com/mysema/query/JPAQueryMutabilityTest.java @@ -13,29 +13,41 @@ */ package com.mysema.query; +import static com.mysema.query.support.Expressions.numberOperation; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import javax.persistence.EntityManager; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; +import com.mysema.query.jpa.HQLTemplates; +import com.mysema.query.jpa.JPQLTemplates; import com.mysema.query.jpa.domain.QCat; import com.mysema.query.jpa.impl.JPAQuery; +import com.mysema.query.types.OperatorImpl; import com.mysema.testutil.JPATestRunner; -@Ignore @RunWith(JPATestRunner.class) public class JPAQueryMutabilityTest implements JPATest { private EntityManager entityManager; + private final OperatorImpl customOperator = new OperatorImpl("CUSTOM", "SIGN"); + + private final JPQLTemplates customTemplates = new HQLTemplates() {{ + add(customOperator, "sign({0})"); + }}; + protected JPAQuery query() { return new JPAQuery(entityManager); } + protected JPAQuery query(JPQLTemplates templates) { + return new JPAQuery(entityManager, templates); + } + @Override public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; @@ -88,6 +100,33 @@ public class JPAQueryMutabilityTest implements JPATest { query2.list(cat); } + @Test + public void Clone_Custom_Templates() { + QCat cat = QCat.cat; + JPAQuery query = query().from(cat); + //attach using the custom templates + query.clone(entityManager, customTemplates) + .uniqueResult(numberOperation(Integer.class, customOperator, cat.floatProperty)); + } + + @Test + public void Clone_Keep_Templates() { + QCat cat = QCat.cat; + JPAQuery query = query(customTemplates).from(cat); + //keep the original templates + query.clone() + .uniqueResult(numberOperation(Integer.class, customOperator, cat.floatProperty)); + } + + @Test(expected = IllegalArgumentException.class) + public void Clone_Lose_Templates() { + QCat cat = QCat.cat; + JPAQuery query = query(customTemplates).from(cat); + //clone using the entitymanager's default templates + query.clone(entityManager) + .uniqueResult(numberOperation(Integer.class, customOperator, cat.floatProperty)); + } + private void assertProjectionEmpty(JPAQuery query) { assertTrue(query.getMetadata().getProjection().isEmpty()); }