CAY-2363 ColumnSelect: unable to use from nested context (cherry picked from commit 518eb2f)
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/a07482cc Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/a07482cc Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/a07482cc Branch: refs/heads/STABLE-4.0 Commit: a07482cc38661a227ee94a3ee2d140b6b794a912 Parents: 7c611dc Author: Nikita Timofeev <stari...@gmail.com> Authored: Mon Sep 11 12:53:41 2017 +0300 Committer: Nikita Timofeev <stari...@gmail.com> Committed: Mon Sep 11 12:55:39 2017 +0300 ---------------------------------------------------------------------- .../cayenne/util/ObjectContextQueryAction.java | 36 ++++++++-- .../apache/cayenne/query/ColumnSelectIT.java | 69 ++++++++++++++++++-- docs/doc/src/main/resources/RELEASE-NOTES.txt | 1 + 3 files changed, 94 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/a07482cc/cayenne-server/src/main/java/org/apache/cayenne/util/ObjectContextQueryAction.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/ObjectContextQueryAction.java b/cayenne-server/src/main/java/org/apache/cayenne/util/ObjectContextQueryAction.java index 3e3e7e8..85f01e0 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/util/ObjectContextQueryAction.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/util/ObjectContextQueryAction.java @@ -20,7 +20,6 @@ package org.apache.cayenne.util; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -34,6 +33,7 @@ import org.apache.cayenne.QueryResponse; import org.apache.cayenne.cache.QueryCache; import org.apache.cayenne.cache.QueryCacheEntryFactory; import org.apache.cayenne.map.EntityInheritanceTree; +import org.apache.cayenne.query.EntityResultSegment; import org.apache.cayenne.query.ObjectIdQuery; import org.apache.cayenne.query.Query; import org.apache.cayenne.query.QueryCacheStrategy; @@ -125,12 +125,21 @@ public abstract class ObjectContextQueryAction { for (response.reset(); response.next();) { if (response.isList()) { - List objects = response.currentList(); if (objects.isEmpty()) { childResponse.addResultList(objects); - } - else { + } else { + + // minor optimization, skip Object[] if there are no persistent objects + boolean haveObjects = metadata.getResultSetMapping() == null; + if(!haveObjects) { + for (Object next : metadata.getResultSetMapping()) { + if(next instanceof EntityResultSegment) { + haveObjects = true; + break; + } + } + } if (merger == null) { merger = new ShallowMergeOperation(targetContext); @@ -141,8 +150,23 @@ public abstract class ObjectContextQueryAction { List<Object> childObjects = new ArrayList<>(objects.size()); for (Object object1 : objects) { - Persistent object = (Persistent) object1; - childObjects.add(merger.merge(object)); + if(object1 instanceof Persistent) { + Persistent object = (Persistent) object1; + childObjects.add(merger.merge(object)); + } else if(haveObjects && object1 instanceof Object[]) { + // merge objects inside Object[] + Object[] parentData = (Object[]) object1; + Object[] childData = new Object[parentData.length]; + System.arraycopy(parentData, 0, childData, 0, parentData.length); + for(int i=0; i<childData.length; i++) { + if(childData[i] instanceof Persistent) { + childData[i] = merger.merge((Persistent)childData[i]); + } + } + childObjects.add(childData); + } else { + childObjects.add(object1); + } } childResponse.addResultList(childObjects); http://git-wip-us.apache.org/repos/asf/cayenne/blob/a07482cc/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java index 25fb80b..21e3d9e 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java @@ -23,15 +23,18 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.sql.Types; import java.text.DateFormat; +import java.util.Date; import java.util.List; import java.util.Locale; import org.apache.cayenne.CayenneRuntimeException; import org.apache.cayenne.Fault; +import org.apache.cayenne.ObjectContext; import org.apache.cayenne.PersistenceState; import org.apache.cayenne.ResultBatchIterator; import org.apache.cayenne.ResultIteratorCallback; import org.apache.cayenne.access.DataContext; +import org.apache.cayenne.configuration.server.ServerRuntime; import org.apache.cayenne.di.Inject; import org.apache.cayenne.exp.Expression; import org.apache.cayenne.exp.ExpressionFactory; @@ -51,12 +54,7 @@ import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.Assert.*; /** * @since 4.0 @@ -68,6 +66,9 @@ public class ColumnSelectIT extends ServerCase { private DataContext context; @Inject + private ServerRuntime runtime; + + @Inject private DBHelper dbHelper; @Inject @@ -986,4 +987,60 @@ public class ColumnSelectIT extends ServerCase { assertEquals(20, names.size()); } + + /* + * Test selection from nested context + */ + + @Test + public void testNestedContextScalarResult() { + ObjectContext childContext = runtime.newContext(context); + + List<String> names = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME) + .select(childContext); + assertEquals(20, names.size()); + for(String name : names) { + assertNotNull(name); + } + } + @Test + public void testNestedContextObjectResult() { + ObjectContext childContext = runtime.newContext(context); + + Property<Artist> artistProperty = Property.createSelf(Artist.class); + List<Artist> artists = ObjectSelect.columnQuery(Artist.class, artistProperty) + .select(childContext); + assertEquals(20, artists.size()); + for(Artist artist : artists) { + assertNotNull(artist); + } + } + + @Test + public void testNestedContextScalarArrayResult() { + ObjectContext childContext = runtime.newContext(context); + + List<Object[]> data = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME, Artist.DATE_OF_BIRTH) + .select(childContext); + assertEquals(20, data.size()); + for(Object[] next : data) { + assertTrue(next[0] instanceof String); + assertTrue(next[1] instanceof Date); + } + } + + @Test + public void testNestedContextMixedResult() { + ObjectContext childContext = runtime.newContext(context); + + Property<Artist> artistProperty = Property.createSelf(Artist.class); + List<Object[]> data = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME, artistProperty) + .select(childContext); + assertEquals(20, data.size()); + for(Object[] next : data) { + assertTrue(next[0] instanceof String); + assertTrue(next[1] instanceof Artist); + } + } + } http://git-wip-us.apache.org/repos/asf/cayenne/blob/a07482cc/docs/doc/src/main/resources/RELEASE-NOTES.txt ---------------------------------------------------------------------- diff --git a/docs/doc/src/main/resources/RELEASE-NOTES.txt b/docs/doc/src/main/resources/RELEASE-NOTES.txt index bd5820f..7a7fa43 100644 --- a/docs/doc/src/main/resources/RELEASE-NOTES.txt +++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt @@ -28,6 +28,7 @@ CAY-2357 Generic select queries silently convert result to nulls if no PK column CAY-2358 NPE when callbacks invoked on null objects CAY-2359 EJBQL: db path in not supported in ORDER BY CAY-2362 ColumnSelect: unable to use Property without type +CAY-2363 ColumnSelect: unable to use from nested context ---------------------------------- Release: 4.0.B1