CAY-2406 Add prefetch-related API to SQLSelect minor refactor additional tests
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/0ca73a17 Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/0ca73a17 Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/0ca73a17 Branch: refs/heads/master Commit: 0ca73a17a6972e66a384e436dcccba11ff943183 Parents: 9d4f6a4 Author: Nikita Timofeev <stari...@gmail.com> Authored: Wed Feb 14 16:33:29 2018 +0300 Committer: Nikita Timofeev <stari...@gmail.com> Committed: Wed Feb 14 16:33:29 2018 +0300 ---------------------------------------------------------------------- .../org/apache/cayenne/query/SQLSelect.java | 2 +- .../org/apache/cayenne/query/SQLTemplate.java | 25 ++++++----- .../org/apache/cayenne/query/SQLTemplateIT.java | 45 ++++++++++++++++++-- 3 files changed, 54 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/0ca73a17/cayenne-server/src/main/java/org/apache/cayenne/query/SQLSelect.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/SQLSelect.java b/cayenne-server/src/main/java/org/apache/cayenne/query/SQLSelect.java index dafc362..2bd0943 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/query/SQLSelect.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/query/SQLSelect.java @@ -240,7 +240,7 @@ public class SQLSelect<T> extends IndirectQuery implements Select<T> { } @Override - public Query createReplacementQuery(EntityResolver resolver) { + protected Query createReplacementQuery(EntityResolver resolver) { Object root; http://git-wip-us.apache.org/repos/asf/cayenne/blob/0ca73a17/cayenne-server/src/main/java/org/apache/cayenne/query/SQLTemplate.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/SQLTemplate.java b/cayenne-server/src/main/java/org/apache/cayenne/query/SQLTemplate.java index c86bb00..acdacfd 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/query/SQLTemplate.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/query/SQLTemplate.java @@ -109,7 +109,7 @@ public class SQLTemplate extends AbstractQuery implements ParameterizedQuery { public void setRoot(Object value) { // allow null root... if (value == null) { - this.root = value; + this.root = null; } else { super.setRoot(value); } @@ -431,7 +431,7 @@ public class SQLTemplate extends AbstractQuery implements ParameterizedQuery { * Returns a collection of configured template keys. */ public synchronized Collection<String> getTemplateKeys() { - return (templates != null) ? templates.keySet() : Collections.<String> emptyList(); + return (templates != null) ? templates.keySet() : Collections.emptyList(); } /** @@ -441,7 +441,7 @@ public class SQLTemplate extends AbstractQuery implements ParameterizedQuery { */ public Map<String, ?> getParams() { Map<String, ?> map = (parameters != null && parameters.length > 0) ? parameters[0] : null; - return (map != null) ? map : Collections.<String, Object> emptyMap(); + return (map != null) ? map : Collections.emptyMap(); } /** @@ -474,7 +474,7 @@ public class SQLTemplate extends AbstractQuery implements ParameterizedQuery { // are not serializable with Hessian... this.parameters = new Map[parameters.length]; for (int i = 0; i < parameters.length; i++) { - this.parameters[i] = parameters[i] != null ? new HashMap<>(parameters[i]) : new HashMap<String, Object>(); + this.parameters[i] = parameters[i] != null ? new HashMap<>(parameters[i]) : new HashMap<>(); } } } @@ -502,22 +502,21 @@ public class SQLTemplate extends AbstractQuery implements ParameterizedQuery { * @since 4.0 */ public void addPrefetch(PrefetchTreeNode prefetchElement) { - if (hasDisjointNode(prefetchElement)) { - throw new CayenneRuntimeException("This query supports only 'joint' and 'disjointById' prefetching semantics."); - } + checkForDisjointNode(prefetchElement); metaData.mergePrefetch(prefetchElement); } - private boolean hasDisjointNode(PrefetchTreeNode prefetchElement) { + /** + * Check for disjoint element and throw if it's found. + * @param prefetchElement to check + */ + private void checkForDisjointNode(PrefetchTreeNode prefetchElement) { if (prefetchElement.isDisjointPrefetch()) { - return true; + throw new CayenneRuntimeException("This query supports only 'joint' and 'disjointById' prefetching semantics."); } for (PrefetchTreeNode child : prefetchElement.getChildren()) { - if (hasDisjointNode(child)) { - return true; - } + checkForDisjointNode(child); } - return false; } /** http://git-wip-us.apache.org/repos/asf/cayenne/blob/0ca73a17/cayenne-server/src/test/java/org/apache/cayenne/query/SQLTemplateIT.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/SQLTemplateIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/SQLTemplateIT.java index 30f4151..2fcbda0 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/query/SQLTemplateIT.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/query/SQLTemplateIT.java @@ -21,6 +21,7 @@ package org.apache.cayenne.query; import org.apache.cayenne.CayenneRuntimeException; import org.apache.cayenne.DataRow; +import org.apache.cayenne.PersistenceState; import org.apache.cayenne.access.DataContext; import org.apache.cayenne.di.Inject; import org.apache.cayenne.map.DataMap; @@ -28,15 +29,14 @@ import org.apache.cayenne.test.jdbc.DBHelper; import org.apache.cayenne.test.jdbc.TableHelper; import org.apache.cayenne.testdo.testmap.Gallery; import org.apache.cayenne.testdo.testmap.Painting; +import org.apache.cayenne.unit.di.DataChannelInterceptor; import org.apache.cayenne.unit.di.server.CayenneProjects; import org.apache.cayenne.unit.di.server.ServerCase; import org.apache.cayenne.unit.di.server.UseServerRuntime; import org.junit.Before; import org.junit.Test; -import java.math.BigInteger; import java.sql.SQLException; -import java.sql.Types; import java.util.List; import static org.junit.Assert.assertEquals; @@ -53,13 +53,20 @@ public class SQLTemplateIT extends ServerCase { @Inject private DBHelper dbHelper; + @Inject + protected DataChannelInterceptor queryInterceptor; + private TableHelper tPainting; + private TableHelper tArtist; + @Before public void setUp() throws Exception { + tArtist = new TableHelper(dbHelper, "ARTIST"); + tArtist.setColumns("ARTIST_ID", "ARTIST_NAME"); + tPainting = new TableHelper(dbHelper, "PAINTING"); - tPainting.setColumns("PAINTING_ID", "ARTIST_ID", "PAINTING_TITLE", "ESTIMATED_PRICE").setColumnTypes( - Types.INTEGER, Types.BIGINT, Types.VARCHAR, Types.DECIMAL); + tPainting.setColumns("PAINTING_ID", "ARTIST_ID", "PAINTING_TITLE", "ESTIMATED_PRICE"); } @Test @@ -184,4 +191,34 @@ public class SQLTemplateIT extends ServerCase { // this should fail as result can't be converted to Gallery class context.performQuery(q1); } + + @Test + public void testSQLTemplateWithDisjointByIdPrefetch() throws Exception { + tArtist.insert(1, "artist1"); + tArtist.insert(2, "artist2"); + + tPainting.insert(1, 1, "p1", 10); + tPainting.insert(2, 2, "p2", 20); + + String sql = "SELECT p.* FROM PAINTING p"; + SQLTemplate q1 = new SQLTemplate(Painting.class, sql); + q1.addPrefetch(Painting.TO_ARTIST.disjointById()); + q1.setColumnNamesCapitalization(CapsStrategy.UPPER); + + @SuppressWarnings("unchecked") + List<Painting> paintings = context.performQuery(q1); + + queryInterceptor.runWithQueriesBlocked(() -> { + for(Painting painting : paintings) { + assertEquals(PersistenceState.COMMITTED, painting.getToArtist().getPersistenceState()); + } + }); + } + + @Test(expected = CayenneRuntimeException.class) + public void testSQLTemplateWithDisjointPrefetch() throws Exception { + String sql = "SELECT p.* FROM PAINTING p"; + SQLTemplate q1 = new SQLTemplate(Painting.class, sql); + q1.addPrefetch(Painting.TO_ARTIST.disjoint()); + } }