You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2014/11/02 08:10:11 UTC

[23/48] Installing Maven Failsafe Plugin

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/IdentityColumnsTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/IdentityColumnsTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/IdentityColumnsTest.java
deleted file mode 100644
index f890b81..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/IdentityColumnsTest.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.access;
-
-import java.util.List;
-
-import org.apache.cayenne.Cayenne;
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.Persistent;
-import org.apache.cayenne.dba.DbAdapter;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.test.jdbc.TableHelper;
-import org.apache.cayenne.testdo.testmap.GeneratedColumnCompKey;
-import org.apache.cayenne.testdo.testmap.GeneratedColumnCompMaster;
-import org.apache.cayenne.testdo.testmap.GeneratedColumnDep;
-import org.apache.cayenne.testdo.testmap.GeneratedColumnTest2;
-import org.apache.cayenne.testdo.testmap.GeneratedColumnTestEntity;
-import org.apache.cayenne.testdo.testmap.GeneratedF1;
-import org.apache.cayenne.testdo.testmap.GeneratedF2;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class IdentityColumnsTest extends ServerCase {
-
-    @Inject
-    protected ObjectContext context;
-
-    @Inject
-    protected DBHelper dbHelper;
-
-    @Inject
-    protected DbAdapter adapter;
-
-    @Inject
-    protected DataNode node;
-
-    protected TableHelper joinTable;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        // TODO: extract in a separate DataMap?
-        dbHelper.deleteAll("GENERATED_JOIN");
-        dbHelper.deleteAll("GENERATED_F1");
-        dbHelper.deleteAll("GENERATED_F2");
-        dbHelper.deleteAll("GENERATED_COLUMN_DEP");
-        dbHelper.deleteAll("GENERATED_COLUMN_TEST");
-
-        joinTable = new TableHelper(dbHelper, "GENERATED_JOIN");
-    }
-
-    /**
-     * Tests a bug casued by the ID Java type mismatch vs the default JDBC type
-     * of the ID column.
-     */
-    public void testCAY823() throws Exception {
-
-        GeneratedColumnTestEntity idObject = context.newObject(GeneratedColumnTestEntity.class);
-
-        String name = "n_" + System.currentTimeMillis();
-        idObject.setName(name);
-
-        idObject.getObjectContext().commitChanges();
-
-        ObjectId id = idObject.getObjectId();
-        context.invalidateObjects(idObject);
-
-        SelectQuery q = new SelectQuery(GeneratedColumnTestEntity.class);
-        q.setPageSize(10);
-        List<?> results = context.performQuery(q);
-        assertEquals(1, results.size());
-
-        // per CAY-823 an attempt to resolve an object results in an exception
-        assertEquals(id, ((Persistent) results.get(0)).getObjectId());
-    }
-
-    public void testNewObject() throws Exception {
-
-        GeneratedColumnTestEntity idObject = context.newObject(GeneratedColumnTestEntity.class);
-
-        String name = "n_" + System.currentTimeMillis();
-        idObject.setName(name);
-
-        idObject.getObjectContext().commitChanges();
-
-        // this will throw an exception if id wasn't generated one way or
-        // another
-        int id = Cayenne.intPKForObject(idObject);
-        assertTrue(id >= 0);
-
-        // make sure that id is the same as id in the DB
-        context.invalidateObjects(idObject);
-        GeneratedColumnTestEntity object = Cayenne.objectForPK(context, GeneratedColumnTestEntity.class, id);
-        assertNotNull(object);
-        assertEquals(name, object.getName());
-    }
-
-    public void testGeneratedJoinInFlattenedRelationship() throws Exception {
-
-        // before saving objects, let's manually access PKGenerator to get a
-        // base PK value
-        // for comparison
-        DbEntity joinTableEntity = context.getEntityResolver().getDbEntity(joinTable.getTableName());
-        DbAttribute pkAttribute = joinTableEntity.getAttribute("ID");
-        Number pk = (Number) adapter.getPkGenerator().generatePk(node, pkAttribute);
-
-        GeneratedF1 f1 = context.newObject(GeneratedF1.class);
-        GeneratedF2 f2 = context.newObject(GeneratedF2.class);
-        f1.addToF2(f2);
-
-        context.commitChanges();
-
-        int id = joinTable.getInt("ID");
-        assertTrue(id > 0);
-
-        // this is a leap of faith that autoincrement-based IDs will not match
-        // PkGenertor provided ids... This sorta works though if pk generator
-        // has a 200
-        // base value
-        if (adapter.supportsGeneratedKeys()) {
-            assertFalse("Looks like auto-increment wasn't used for the join table. ID: " + id, id == pk.intValue() + 1);
-        } else {
-            assertEquals(id, pk.intValue() + 1);
-        }
-    }
-
-    /**
-     * Tests CAY-422 bug.
-     */
-    public void testUnrelatedUpdate() throws Exception {
-
-        GeneratedColumnTestEntity m = context.newObject(GeneratedColumnTestEntity.class);
-
-        m.setName("m");
-
-        GeneratedColumnDep d = context.newObject(GeneratedColumnDep.class);
-        d.setName("d");
-        d.setToMaster(m);
-        context.commitChanges();
-
-        context.invalidateObjects(m, d);
-
-        context.prepareForAccess(d, null, false);
-
-        // this line caused CAY-422 error
-        d.getToMaster();
-
-        d.setName("new name");
-        context.commitChanges();
-    }
-
-    /**
-     * Tests that insert in two tables with identity pk does not generate a
-     * conflict. See CAY-341 for the original bug.
-     */
-    public void testMultipleNewObjectsSeparateTables() throws Exception {
-
-        GeneratedColumnTestEntity idObject1 = context.newObject(GeneratedColumnTestEntity.class);
-        idObject1.setName("o1");
-
-        GeneratedColumnTest2 idObject2 = context.newObject(GeneratedColumnTest2.class);
-        idObject2.setName("o2");
-
-        context.commitChanges();
-    }
-
-    public void testMultipleNewObjects() throws Exception {
-
-        String[] names = new String[] { "n1_" + System.currentTimeMillis(), "n2_" + System.currentTimeMillis(),
-                "n3_" + System.currentTimeMillis() };
-
-        GeneratedColumnTestEntity[] idObjects = new GeneratedColumnTestEntity[] {
-                context.newObject(GeneratedColumnTestEntity.class), context.newObject(GeneratedColumnTestEntity.class),
-                context.newObject(GeneratedColumnTestEntity.class) };
-
-        for (int i = 0; i < idObjects.length; i++) {
-            idObjects[i].setName(names[i]);
-        }
-
-        context.commitChanges();
-
-        int[] ids = new int[idObjects.length];
-        for (int i = 0; i < idObjects.length; i++) {
-            ids[i] = Cayenne.intPKForObject(idObjects[i]);
-            assertTrue(ids[i] > 0);
-        }
-
-        context.invalidateObjects(idObjects);
-
-        for (int i = 0; i < ids.length; i++) {
-            GeneratedColumnTestEntity object = Cayenne.objectForPK(context, GeneratedColumnTestEntity.class, ids[i]);
-            assertNotNull(object);
-            assertEquals(names[i], object.getName());
-        }
-    }
-
-    public void testCompoundPKWithGeneratedColumn() throws Exception {
-        if (adapter.supportsGeneratedKeys()) {
-            // only works for generated keys, as the entity tested has one
-            // Cayenne
-            // auto-pk and one generated key
-
-            String masterName = "m_" + System.currentTimeMillis();
-            String depName1 = "dep1_" + System.currentTimeMillis();
-            String depName2 = "dep2_" + System.currentTimeMillis();
-
-            GeneratedColumnCompMaster master = context.newObject(GeneratedColumnCompMaster.class);
-            master.setName(masterName);
-
-            GeneratedColumnCompKey dep1 = context.newObject(GeneratedColumnCompKey.class);
-            dep1.setName(depName1);
-            dep1.setToMaster(master);
-
-            GeneratedColumnCompKey dep2 = context.newObject(GeneratedColumnCompKey.class);
-            dep2.setName(depName2);
-            dep2.setToMaster(master);
-
-            context.commitChanges();
-
-            int masterId = Cayenne.intPKForObject(master);
-
-            ObjectId id2 = dep2.getObjectId();
-
-            // check propagated id
-            Number propagatedID2 = (Number) id2.getIdSnapshot().get(GeneratedColumnCompKey.PROPAGATED_PK_PK_COLUMN);
-            assertNotNull(propagatedID2);
-            assertEquals(masterId, propagatedID2.intValue());
-
-            // check Cayenne-generated ID
-            Number cayenneGeneratedID2 = (Number) id2.getIdSnapshot().get(GeneratedColumnCompKey.AUTO_PK_PK_COLUMN);
-            assertNotNull(cayenneGeneratedID2);
-
-            // check DB-generated ID
-            Number dbGeneratedID2 = (Number) id2.getIdSnapshot().get(GeneratedColumnCompKey.GENERATED_COLUMN_PK_COLUMN);
-            assertNotNull(dbGeneratedID2);
-
-            context.invalidateObjects(master, dep1, dep2);
-
-            Object fetchedDep2 = Cayenne.objectForPK(context, id2);
-            assertNotNull(fetchedDep2);
-        }
-    }
-
-    public void testUpdateDependentWithNewMaster() throws Exception {
-
-        GeneratedColumnTestEntity master1 = context.newObject(GeneratedColumnTestEntity.class);
-        master1.setName("aaa");
-
-        GeneratedColumnDep dependent = context.newObject(GeneratedColumnDep.class);
-        dependent.setName("aaa");
-        dependent.setToMaster(master1);
-
-        context.commitChanges();
-
-        // change master
-        GeneratedColumnTestEntity master2 = context.newObject(GeneratedColumnTestEntity.class);
-        master2.setName("bbb");
-
-        // TESTING THIS
-        dependent.setToMaster(master2);
-        context.commitChanges();
-
-        int id1 = Cayenne.intPKForObject(master2);
-        assertTrue(id1 >= 0);
-
-        int id2 = Cayenne.intPKForObject(dependent);
-        assertTrue(id2 >= 0);
-        assertEquals(id1, id2);
-
-        context.invalidateObjects(master2, dependent);
-
-        assertNotNull(Cayenne.objectForPK(context, GeneratedColumnTestEntity.class, id1));
-        assertNotNull(Cayenne.objectForPK(context, GeneratedColumnDep.class, id2));
-    }
-
-    public void testGeneratedDefaultValue() throws Exception {
-
-        // fail("TODO: test insert with DEFAULT generated column...need custom
-        // SQL to
-        // build such table");
-    }
-
-    public void testPropagateToDependent() throws Exception {
-
-        GeneratedColumnTestEntity idObject = context.newObject(GeneratedColumnTestEntity.class);
-        idObject.setName("aaa");
-
-        GeneratedColumnDep dependent = idObject.getObjectContext().newObject(GeneratedColumnDep.class);
-        dependent.setName("aaa");
-        dependent.setToMaster(idObject);
-
-        context.commitChanges();
-
-        // this will throw an exception if id wasn't generated
-        int id1 = Cayenne.intPKForObject(idObject);
-        assertTrue(id1 >= 0);
-
-        int id2 = Cayenne.intPKForObject(dependent);
-        assertTrue(id2 >= 0);
-
-        assertEquals(id1, id2);
-
-        // refetch from DB
-        context.invalidateObjects(idObject, dependent);
-
-        assertNotNull(Cayenne.objectForPK(context, GeneratedColumnTestEntity.class, id1));
-        assertNotNull(Cayenne.objectForPK(context, GeneratedColumnDep.class, id2));
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/IncrementalFaultListIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/IncrementalFaultListIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/IncrementalFaultListIT.java
new file mode 100644
index 0000000..c233c59
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/IncrementalFaultListIT.java
@@ -0,0 +1,46 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.access;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.apache.cayenne.util.Util;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class IncrementalFaultListIT extends ServerCase {
+
+	@Inject
+	protected DataContext context;
+
+	public void testSerialization() throws Exception {
+		SelectQuery query = new SelectQuery(Artist.class);
+		query.setPageSize(10);
+		
+		IncrementalFaultList<Artist> i1 = new IncrementalFaultList<Artist>(context, query, 10);
+		IncrementalFaultList<Artist> i2 = Util.cloneViaSerialization(i1);
+		
+		assertNotNull(i2);
+		assertEquals(i1.getMaxFetchSize(), i2.getMaxFetchSize());
+		assertEquals(i1.getClass(), i2.getClass());
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/IncrementalFaultListTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/IncrementalFaultListTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/IncrementalFaultListTest.java
deleted file mode 100644
index 72c7e03..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/IncrementalFaultListTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-package org.apache.cayenne.access;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.testdo.testmap.Artist;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-import org.apache.cayenne.util.Util;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class IncrementalFaultListTest extends ServerCase {
-
-	@Inject
-	protected DataContext context;
-
-	public void testSerialization() throws Exception {
-		SelectQuery query = new SelectQuery(Artist.class);
-		query.setPageSize(10);
-		
-		IncrementalFaultList<Artist> i1 = new IncrementalFaultList<Artist>(context, query, 10);
-		IncrementalFaultList<Artist> i2 = Util.cloneViaSerialization(i1);
-		
-		assertNotNull(i2);
-		assertEquals(i1.getMaxFetchSize(), i2.getMaxFetchSize());
-		assertEquals(i1.getClass(), i2.getClass());
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/JointPrefetchIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/JointPrefetchIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/JointPrefetchIT.java
new file mode 100644
index 0000000..0fbfdc7
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/JointPrefetchIT.java
@@ -0,0 +1,495 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.access;
+
+import org.apache.cayenne.DataObject;
+import org.apache.cayenne.DataRow;
+import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.PersistenceState;
+import org.apache.cayenne.Persistent;
+import org.apache.cayenne.ValueHolder;
+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;
+import org.apache.cayenne.map.ObjAttribute;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.query.PrefetchTreeNode;
+import org.apache.cayenne.query.SQLTemplate;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.query.SortOrder;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.testmap.Artist;
+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.UnitTestClosure;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.sql.Date;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Tests joint prefetch handling by Cayenne access stack.
+ */
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class JointPrefetchIT extends ServerCase {
+
+    @Inject
+    protected DataContext context;
+
+    @Inject
+    protected ServerRuntime runtime;
+
+    @Inject
+    protected DataChannelInterceptor queryInterceptor;
+
+    @Inject
+    protected DBHelper dbHelper;
+
+    protected TableHelper tArtist;
+    protected TableHelper tGallery;
+    protected TableHelper tPainting;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("PAINTING");
+        dbHelper.deleteAll("ARTIST_EXHIBIT"); // table artist_exhibit depends on artist and exhibit
+        dbHelper.deleteAll("ARTIST");
+        dbHelper.deleteAll("EXHIBIT"); // table exhibit depends on gallery
+        dbHelper.deleteAll("GALLERY");
+
+        tArtist = new TableHelper(dbHelper, "ARTIST");
+        tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
+
+        tGallery = new TableHelper(dbHelper, "GALLERY");
+        tGallery.setColumns("GALLERY_ID", "GALLERY_NAME");
+
+        tPainting = new TableHelper(dbHelper, "PAINTING");
+        tPainting.setColumns(
+                "PAINTING_ID",
+                "PAINTING_TITLE",
+                "ARTIST_ID",
+                "ESTIMATED_PRICE",
+                "GALLERY_ID");
+    }
+
+    protected void createJointPrefetchDataSet1() throws Exception {
+        tGallery.insert(33001, "G1");
+        tGallery.insert(33002, "G2");
+        tArtist.insert(33001, "artist1");
+        tArtist.insert(33002, "artist2");
+        tArtist.insert(33003, "artist3");
+        tPainting.insert(33001, "P_artist11", 33001, 1000, 33001);
+        tPainting.insert(33002, "P_artist12", 33001, 2000, 33001);
+        tPainting.insert(33003, "P_artist21", 33002, 3000, 33002);
+    }
+
+    protected void createJointPrefetchDataSet2() throws Exception {
+        tGallery.insert(33001, "G1");
+        tGallery.insert(33002, "G2");
+        tArtist.insert(33001, "artist1");
+        tArtist.insert(33002, "artist2");
+        tArtist.insert(33003, "artist3");
+        tPainting.insert(33001, "P_artist11", 33001, 1000, 33001);
+        tPainting.insert(33002, "P_artist12", 33001, 2000, 33001);
+        tPainting.insert(33003, "P_artist21", 33002, 3000, 33002);
+    }
+
+    public void testJointPrefetch_ToOne_FetchLimit() throws Exception {
+        createJointPrefetchDataSet1();
+
+        SelectQuery q = new SelectQuery(Painting.class);
+        q.setFetchLimit(2);
+        q.setFetchOffset(0);
+        q.addOrdering("db:PAINTING_ID", SortOrder.ASCENDING);
+        q.addPrefetch(Painting.TO_ARTIST_PROPERTY).setSemantics(
+                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+
+        final List<?> objects = context.performQuery(q);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                assertEquals(2, objects.size());
+
+                Iterator<?> it = objects.iterator();
+                while (it.hasNext()) {
+                    Painting p = (Painting) it.next();
+                    Artist target = p.getToArtist();
+                    assertNotNull(target);
+                    assertEquals(PersistenceState.COMMITTED, target.getPersistenceState());
+                }
+            }
+        });
+    }
+
+    public void testJointPrefetch_ToMany_FetchLimit() throws Exception {
+        createJointPrefetchDataSet1();
+
+        SelectQuery q = new SelectQuery(Artist.class);
+        q.setFetchLimit(2);
+        q.setFetchOffset(0);
+        q.addOrdering("db:ARTIST_ID", SortOrder.ASCENDING);
+        q.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(
+                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+
+        final List<?> objects = context.performQuery(q);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                // herein lies the limitation of prefetching combined with fetch limit -
+                // we got fewer artists than we wanted
+                assertEquals(1, objects.size());
+
+                Iterator<?> it = objects.iterator();
+                while (it.hasNext()) {
+                    Artist a = (Artist) it.next();
+                    List<Painting> targets = a.getPaintingArray();
+                    assertNotNull(targets);
+                    for (Painting p : targets) {
+                        assertEquals(PersistenceState.COMMITTED, p.getPersistenceState());
+                    }
+                }
+            }
+        });
+    }
+
+    public void testJointPrefetchDataRows() throws Exception {
+        createJointPrefetchDataSet1();
+
+        // query with to-many joint prefetches
+        SelectQuery q = new SelectQuery(Painting.class);
+        q.addOrdering("db:PAINTING_ID", SortOrder.ASCENDING);
+        q.setFetchingDataRows(true);
+        q.addPrefetch(Painting.TO_ARTIST_PROPERTY).setSemantics(
+                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+
+        final List<?> rows = context.performQuery(q);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                assertEquals(3, rows.size());
+
+                // row should contain columns from both entities minus those duplicated in
+                // a
+                // join...
+
+                int rowWidth = context
+                        .getEntityResolver()
+                        .getDbEntity("ARTIST")
+                        .getAttributes()
+                        .size()
+                        + context
+                                .getEntityResolver()
+                                .getDbEntity("PAINTING")
+                                .getAttributes()
+                                .size();
+                Iterator<?> it = rows.iterator();
+                while (it.hasNext()) {
+                    DataRow row = (DataRow) it.next();
+                    assertEquals("" + row, rowWidth, row.size());
+
+                    // assert columns presence
+                    assertTrue(row + "", row.containsKey("PAINTING_ID"));
+                    assertTrue(row + "", row.containsKey("ARTIST_ID"));
+                    assertTrue(row + "", row.containsKey("GALLERY_ID"));
+                    assertTrue(row + "", row.containsKey("PAINTING_TITLE"));
+                    assertTrue(row + "", row.containsKey("ESTIMATED_PRICE"));
+                    assertTrue(row + "", row.containsKey("toArtist.ARTIST_NAME"));
+                    assertTrue(row + "", row.containsKey("toArtist.DATE_OF_BIRTH"));
+                }
+            }
+        });
+    }
+
+    public void testJointPrefetchSQLTemplate() throws Exception {
+        createJointPrefetchDataSet1();
+
+        // correctly naming columns is the key..
+        SQLTemplate q = new SQLTemplate(
+                Artist.class,
+                "SELECT distinct "
+                        + "#result('ESTIMATED_PRICE' 'BigDecimal' '' 'paintingArray.ESTIMATED_PRICE'), "
+                        + "#result('PAINTING_TITLE' 'String' '' 'paintingArray.PAINTING_TITLE'), "
+                        + "#result('GALLERY_ID' 'int' '' 'paintingArray.GALLERY_ID'), "
+                        + "#result('PAINTING_ID' 'int' '' 'paintingArray.PAINTING_ID'), "
+                        + "#result('ARTIST_NAME' 'String'), "
+                        + "#result('DATE_OF_BIRTH' 'java.util.Date'), "
+                        + "#result('t0.ARTIST_ID' 'int' '' 'ARTIST_ID') "
+                        + "FROM ARTIST t0, PAINTING t1 "
+                        + "WHERE t0.ARTIST_ID = t1.ARTIST_ID");
+
+        PrefetchTreeNode prefetch = q.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY);
+        assertEquals(
+                "Default semantics for SQLTemplate is assumed to be joint.",
+                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS,
+                prefetch.getSemantics());
+        q.setFetchingDataRows(false);
+
+        final List<?> objects = context.performQuery(q);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                // without OUTER join we will get fewer objects...
+                assertEquals(2, objects.size());
+
+                Iterator<?> it = objects.iterator();
+                while (it.hasNext()) {
+                    Artist a = (Artist) it.next();
+                    List<?> list = a.getPaintingArray();
+
+                    assertNotNull(list);
+                    assertFalse(((ValueHolder) list).isFault());
+                    assertTrue(list.size() > 0);
+
+                    Iterator<?> children = list.iterator();
+                    while (children.hasNext()) {
+                        Painting p = (Painting) children.next();
+                        assertEquals(PersistenceState.COMMITTED, p.getPersistenceState());
+
+                        // make sure properties are not null..
+                        assertNotNull(p.getPaintingTitle());
+                    }
+                }
+            }
+        });
+    }
+
+    public void testJointPrefetchToOne() throws Exception {
+        createJointPrefetchDataSet1();
+
+        // query with to-many joint prefetches
+        SelectQuery q = new SelectQuery(Painting.class);
+        q.addOrdering("db:PAINTING_ID", SortOrder.ASCENDING);
+        q.addPrefetch(Painting.TO_ARTIST_PROPERTY).setSemantics(
+                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+
+        final List<?> objects = context.performQuery(q);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                assertEquals(3, objects.size());
+
+                Iterator<?> it = objects.iterator();
+                while (it.hasNext()) {
+                    Painting p = (Painting) it.next();
+                    Artist target = p.getToArtist();
+                    assertNotNull(target);
+                    assertEquals(PersistenceState.COMMITTED, target.getPersistenceState());
+                }
+            }
+        });
+    }
+
+    /**
+     * Tests that joined entities can have non-standard type mappings.
+     */
+    public void testJointPrefetchDataTypes() throws Exception {
+        // prepare... can't load from XML, as it doesn't yet support dates..
+        SQLTemplate artistSQL = new SQLTemplate(
+                Artist.class,
+                "insert into ARTIST (ARTIST_ID, ARTIST_NAME, DATE_OF_BIRTH) "
+                        + "values (33001, 'a1', #bind($date 'DATE'))");
+        artistSQL.setParameters(Collections.singletonMap(
+                "date",
+                new Date(System.currentTimeMillis())));
+        SQLTemplate paintingSQL = new SQLTemplate(
+                Painting.class,
+                "INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ARTIST_ID, ESTIMATED_PRICE) "
+                        + "VALUES (33001, 'p1', 33001, 1000)");
+
+        context.performNonSelectingQuery(artistSQL);
+        context.performNonSelectingQuery(paintingSQL);
+
+        // test
+        SelectQuery q = new SelectQuery(Painting.class);
+        q.addPrefetch(Painting.TO_ARTIST_PROPERTY).setSemantics(
+                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+
+        ObjEntity artistE = context.getEntityResolver().getObjEntity("Artist");
+        ObjAttribute dateOfBirth = artistE.getAttribute("dateOfBirth");
+        assertEquals("java.util.Date", dateOfBirth.getType());
+        dateOfBirth.setType("java.sql.Date");
+        try {
+            final List<?> objects = context.performQuery(q);
+
+            queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+                public void execute() {
+                    assertEquals(1, objects.size());
+
+                    Iterator<?> it = objects.iterator();
+                    while (it.hasNext()) {
+                        Painting p = (Painting) it.next();
+                        Artist a = p.getToArtist();
+                        assertNotNull(a);
+                        assertNotNull(a.getDateOfBirth());
+                        assertTrue(a.getDateOfBirth().getClass().getName(), Date.class
+                                .isAssignableFrom(a.getDateOfBirth().getClass()));
+                    }
+                }
+            });
+        }
+        finally {
+            dateOfBirth.setType("java.util.Date");
+        }
+    }
+
+    public void testJointPrefetchToMany() throws Exception {
+        createJointPrefetchDataSet1();
+
+        // query with to-many joint prefetches
+        SelectQuery q = new SelectQuery(Artist.class);
+        q.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(
+                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+
+        final List<?> objects = context.performQuery(q);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                assertEquals(3, objects.size());
+
+                Iterator<?> it = objects.iterator();
+                while (it.hasNext()) {
+                    Artist a = (Artist) it.next();
+                    List<?> list = a.getPaintingArray();
+
+                    assertNotNull(list);
+                    assertFalse(((ValueHolder) list).isFault());
+
+                    Iterator<?> children = list.iterator();
+                    while (children.hasNext()) {
+                        Painting p = (Painting) children.next();
+                        assertEquals(PersistenceState.COMMITTED, p.getPersistenceState());
+                        // make sure properties are not null..
+                        assertNotNull(p.getPaintingTitle());
+                    }
+                }
+            }
+        });
+    }
+
+    public void testJointPrefetchToManyNonConflictingQualifier() throws Exception {
+        createJointPrefetchDataSet1();
+
+        // query with to-many joint prefetches and qualifier that doesn't match
+        // prefetch....
+        Expression qualifier = ExpressionFactory.matchExp(
+                Artist.ARTIST_NAME_PROPERTY,
+                "artist1");
+        SelectQuery q = new SelectQuery(Artist.class, qualifier);
+        q.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(
+                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+
+        final List<?> objects = context.performQuery(q);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                assertEquals(1, objects.size());
+
+                Artist a = (Artist) objects.get(0);
+                List<?> list = a.getPaintingArray();
+
+                assertNotNull(list);
+                assertFalse(((ValueHolder) list).isFault());
+                assertEquals(2, list.size());
+
+                Iterator<?> children = list.iterator();
+                while (children.hasNext()) {
+                    Painting p = (Painting) children.next();
+                    assertEquals(PersistenceState.COMMITTED, p.getPersistenceState());
+                    // make sure properties are not null..
+                    assertNotNull(p.getPaintingTitle());
+                }
+
+                // assert no duplicates
+                Set s = new HashSet(list);
+                assertEquals(s.size(), list.size());
+            }
+        });
+    }
+
+    public void testJointPrefetchMultiStep() throws Exception {
+        createJointPrefetchDataSet2();
+
+        // query with to-many joint prefetches
+        SelectQuery q = new SelectQuery(Artist.class);
+        q
+                .addPrefetch(
+                        Artist.PAINTING_ARRAY_PROPERTY
+                                + "."
+                                + Painting.TO_GALLERY_PROPERTY)
+                .setSemantics(PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+
+        final DataContext context = this.context;
+
+        // make sure phantomly prefetched objects are not deallocated
+        context.getObjectStore().objectMap = new HashMap<Object, Persistent>();
+
+        // sanity check...
+        DataObject g1 = (DataObject) context.getGraphManager().getNode(
+                new ObjectId("Gallery", Gallery.GALLERY_ID_PK_COLUMN, 33001));
+        assertNull(g1);
+
+        final List<?> objects = context.performQuery(q);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                assertEquals(3, objects.size());
+
+                Iterator<?> it = objects.iterator();
+                while (it.hasNext()) {
+                    Artist a = (Artist) it.next();
+                    ValueHolder list = (ValueHolder) a.getPaintingArray();
+
+                    assertNotNull(list);
+
+                    // intermediate relationship is not fetched...
+                    assertTrue(list.isFault());
+                }
+
+                // however both galleries must be in memory...
+                DataObject g1 = (DataObject) context.getGraphManager().getNode(
+                        new ObjectId("Gallery", Gallery.GALLERY_ID_PK_COLUMN, 33001));
+                assertNotNull(g1);
+                assertEquals(PersistenceState.COMMITTED, g1.getPersistenceState());
+                DataObject g2 = (DataObject) context.getGraphManager().getNode(
+                        new ObjectId("Gallery", Gallery.GALLERY_ID_PK_COLUMN, 33002));
+                assertNotNull(g2);
+                assertEquals(PersistenceState.COMMITTED, g2.getPersistenceState());
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/JointPrefetchTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/JointPrefetchTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/JointPrefetchTest.java
deleted file mode 100644
index 966388a..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/JointPrefetchTest.java
+++ /dev/null
@@ -1,495 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.access;
-
-import java.sql.Date;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.cayenne.DataObject;
-import org.apache.cayenne.DataRow;
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.PersistenceState;
-import org.apache.cayenne.Persistent;
-import org.apache.cayenne.ValueHolder;
-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;
-import org.apache.cayenne.map.ObjAttribute;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.query.PrefetchTreeNode;
-import org.apache.cayenne.query.SQLTemplate;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.query.SortOrder;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.test.jdbc.TableHelper;
-import org.apache.cayenne.testdo.testmap.Artist;
-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.UnitTestClosure;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-/**
- * Tests joint prefetch handling by Cayenne access stack.
- */
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class JointPrefetchTest extends ServerCase {
-
-    @Inject
-    protected DataContext context;
-
-    @Inject
-    protected ServerRuntime runtime;
-
-    @Inject
-    protected DataChannelInterceptor queryInterceptor;
-
-    @Inject
-    protected DBHelper dbHelper;
-
-    protected TableHelper tArtist;
-    protected TableHelper tGallery;
-    protected TableHelper tPainting;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("PAINTING");
-        dbHelper.deleteAll("ARTIST_EXHIBIT"); // table artist_exhibit depends on artist and exhibit
-        dbHelper.deleteAll("ARTIST");
-        dbHelper.deleteAll("EXHIBIT"); // table exhibit depends on gallery
-        dbHelper.deleteAll("GALLERY");
-
-        tArtist = new TableHelper(dbHelper, "ARTIST");
-        tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
-
-        tGallery = new TableHelper(dbHelper, "GALLERY");
-        tGallery.setColumns("GALLERY_ID", "GALLERY_NAME");
-
-        tPainting = new TableHelper(dbHelper, "PAINTING");
-        tPainting.setColumns(
-                "PAINTING_ID",
-                "PAINTING_TITLE",
-                "ARTIST_ID",
-                "ESTIMATED_PRICE",
-                "GALLERY_ID");
-    }
-
-    protected void createJointPrefetchDataSet1() throws Exception {
-        tGallery.insert(33001, "G1");
-        tGallery.insert(33002, "G2");
-        tArtist.insert(33001, "artist1");
-        tArtist.insert(33002, "artist2");
-        tArtist.insert(33003, "artist3");
-        tPainting.insert(33001, "P_artist11", 33001, 1000, 33001);
-        tPainting.insert(33002, "P_artist12", 33001, 2000, 33001);
-        tPainting.insert(33003, "P_artist21", 33002, 3000, 33002);
-    }
-
-    protected void createJointPrefetchDataSet2() throws Exception {
-        tGallery.insert(33001, "G1");
-        tGallery.insert(33002, "G2");
-        tArtist.insert(33001, "artist1");
-        tArtist.insert(33002, "artist2");
-        tArtist.insert(33003, "artist3");
-        tPainting.insert(33001, "P_artist11", 33001, 1000, 33001);
-        tPainting.insert(33002, "P_artist12", 33001, 2000, 33001);
-        tPainting.insert(33003, "P_artist21", 33002, 3000, 33002);
-    }
-
-    public void testJointPrefetch_ToOne_FetchLimit() throws Exception {
-        createJointPrefetchDataSet1();
-
-        SelectQuery q = new SelectQuery(Painting.class);
-        q.setFetchLimit(2);
-        q.setFetchOffset(0);
-        q.addOrdering("db:PAINTING_ID", SortOrder.ASCENDING);
-        q.addPrefetch(Painting.TO_ARTIST_PROPERTY).setSemantics(
-                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
-
-        final List<?> objects = context.performQuery(q);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                assertEquals(2, objects.size());
-
-                Iterator<?> it = objects.iterator();
-                while (it.hasNext()) {
-                    Painting p = (Painting) it.next();
-                    Artist target = p.getToArtist();
-                    assertNotNull(target);
-                    assertEquals(PersistenceState.COMMITTED, target.getPersistenceState());
-                }
-            }
-        });
-    }
-
-    public void testJointPrefetch_ToMany_FetchLimit() throws Exception {
-        createJointPrefetchDataSet1();
-
-        SelectQuery q = new SelectQuery(Artist.class);
-        q.setFetchLimit(2);
-        q.setFetchOffset(0);
-        q.addOrdering("db:ARTIST_ID", SortOrder.ASCENDING);
-        q.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(
-                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
-
-        final List<?> objects = context.performQuery(q);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                // herein lies the limitation of prefetching combined with fetch limit -
-                // we got fewer artists than we wanted
-                assertEquals(1, objects.size());
-
-                Iterator<?> it = objects.iterator();
-                while (it.hasNext()) {
-                    Artist a = (Artist) it.next();
-                    List<Painting> targets = a.getPaintingArray();
-                    assertNotNull(targets);
-                    for (Painting p : targets) {
-                        assertEquals(PersistenceState.COMMITTED, p.getPersistenceState());
-                    }
-                }
-            }
-        });
-    }
-
-    public void testJointPrefetchDataRows() throws Exception {
-        createJointPrefetchDataSet1();
-
-        // query with to-many joint prefetches
-        SelectQuery q = new SelectQuery(Painting.class);
-        q.addOrdering("db:PAINTING_ID", SortOrder.ASCENDING);
-        q.setFetchingDataRows(true);
-        q.addPrefetch(Painting.TO_ARTIST_PROPERTY).setSemantics(
-                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
-
-        final List<?> rows = context.performQuery(q);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                assertEquals(3, rows.size());
-
-                // row should contain columns from both entities minus those duplicated in
-                // a
-                // join...
-
-                int rowWidth = context
-                        .getEntityResolver()
-                        .getDbEntity("ARTIST")
-                        .getAttributes()
-                        .size()
-                        + context
-                                .getEntityResolver()
-                                .getDbEntity("PAINTING")
-                                .getAttributes()
-                                .size();
-                Iterator<?> it = rows.iterator();
-                while (it.hasNext()) {
-                    DataRow row = (DataRow) it.next();
-                    assertEquals("" + row, rowWidth, row.size());
-
-                    // assert columns presence
-                    assertTrue(row + "", row.containsKey("PAINTING_ID"));
-                    assertTrue(row + "", row.containsKey("ARTIST_ID"));
-                    assertTrue(row + "", row.containsKey("GALLERY_ID"));
-                    assertTrue(row + "", row.containsKey("PAINTING_TITLE"));
-                    assertTrue(row + "", row.containsKey("ESTIMATED_PRICE"));
-                    assertTrue(row + "", row.containsKey("toArtist.ARTIST_NAME"));
-                    assertTrue(row + "", row.containsKey("toArtist.DATE_OF_BIRTH"));
-                }
-            }
-        });
-    }
-
-    public void testJointPrefetchSQLTemplate() throws Exception {
-        createJointPrefetchDataSet1();
-
-        // correctly naming columns is the key..
-        SQLTemplate q = new SQLTemplate(
-                Artist.class,
-                "SELECT distinct "
-                        + "#result('ESTIMATED_PRICE' 'BigDecimal' '' 'paintingArray.ESTIMATED_PRICE'), "
-                        + "#result('PAINTING_TITLE' 'String' '' 'paintingArray.PAINTING_TITLE'), "
-                        + "#result('GALLERY_ID' 'int' '' 'paintingArray.GALLERY_ID'), "
-                        + "#result('PAINTING_ID' 'int' '' 'paintingArray.PAINTING_ID'), "
-                        + "#result('ARTIST_NAME' 'String'), "
-                        + "#result('DATE_OF_BIRTH' 'java.util.Date'), "
-                        + "#result('t0.ARTIST_ID' 'int' '' 'ARTIST_ID') "
-                        + "FROM ARTIST t0, PAINTING t1 "
-                        + "WHERE t0.ARTIST_ID = t1.ARTIST_ID");
-
-        PrefetchTreeNode prefetch = q.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY);
-        assertEquals(
-                "Default semantics for SQLTemplate is assumed to be joint.",
-                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS,
-                prefetch.getSemantics());
-        q.setFetchingDataRows(false);
-
-        final List<?> objects = context.performQuery(q);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                // without OUTER join we will get fewer objects...
-                assertEquals(2, objects.size());
-
-                Iterator<?> it = objects.iterator();
-                while (it.hasNext()) {
-                    Artist a = (Artist) it.next();
-                    List<?> list = a.getPaintingArray();
-
-                    assertNotNull(list);
-                    assertFalse(((ValueHolder) list).isFault());
-                    assertTrue(list.size() > 0);
-
-                    Iterator<?> children = list.iterator();
-                    while (children.hasNext()) {
-                        Painting p = (Painting) children.next();
-                        assertEquals(PersistenceState.COMMITTED, p.getPersistenceState());
-
-                        // make sure properties are not null..
-                        assertNotNull(p.getPaintingTitle());
-                    }
-                }
-            }
-        });
-    }
-
-    public void testJointPrefetchToOne() throws Exception {
-        createJointPrefetchDataSet1();
-
-        // query with to-many joint prefetches
-        SelectQuery q = new SelectQuery(Painting.class);
-        q.addOrdering("db:PAINTING_ID", SortOrder.ASCENDING);
-        q.addPrefetch(Painting.TO_ARTIST_PROPERTY).setSemantics(
-                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
-
-        final List<?> objects = context.performQuery(q);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                assertEquals(3, objects.size());
-
-                Iterator<?> it = objects.iterator();
-                while (it.hasNext()) {
-                    Painting p = (Painting) it.next();
-                    Artist target = p.getToArtist();
-                    assertNotNull(target);
-                    assertEquals(PersistenceState.COMMITTED, target.getPersistenceState());
-                }
-            }
-        });
-    }
-
-    /**
-     * Tests that joined entities can have non-standard type mappings.
-     */
-    public void testJointPrefetchDataTypes() throws Exception {
-        // prepare... can't load from XML, as it doesn't yet support dates..
-        SQLTemplate artistSQL = new SQLTemplate(
-                Artist.class,
-                "insert into ARTIST (ARTIST_ID, ARTIST_NAME, DATE_OF_BIRTH) "
-                        + "values (33001, 'a1', #bind($date 'DATE'))");
-        artistSQL.setParameters(Collections.singletonMap(
-                "date",
-                new Date(System.currentTimeMillis())));
-        SQLTemplate paintingSQL = new SQLTemplate(
-                Painting.class,
-                "INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ARTIST_ID, ESTIMATED_PRICE) "
-                        + "VALUES (33001, 'p1', 33001, 1000)");
-
-        context.performNonSelectingQuery(artistSQL);
-        context.performNonSelectingQuery(paintingSQL);
-
-        // test
-        SelectQuery q = new SelectQuery(Painting.class);
-        q.addPrefetch(Painting.TO_ARTIST_PROPERTY).setSemantics(
-                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
-
-        ObjEntity artistE = context.getEntityResolver().getObjEntity("Artist");
-        ObjAttribute dateOfBirth = artistE.getAttribute("dateOfBirth");
-        assertEquals("java.util.Date", dateOfBirth.getType());
-        dateOfBirth.setType("java.sql.Date");
-        try {
-            final List<?> objects = context.performQuery(q);
-
-            queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-                public void execute() {
-                    assertEquals(1, objects.size());
-
-                    Iterator<?> it = objects.iterator();
-                    while (it.hasNext()) {
-                        Painting p = (Painting) it.next();
-                        Artist a = p.getToArtist();
-                        assertNotNull(a);
-                        assertNotNull(a.getDateOfBirth());
-                        assertTrue(a.getDateOfBirth().getClass().getName(), Date.class
-                                .isAssignableFrom(a.getDateOfBirth().getClass()));
-                    }
-                }
-            });
-        }
-        finally {
-            dateOfBirth.setType("java.util.Date");
-        }
-    }
-
-    public void testJointPrefetchToMany() throws Exception {
-        createJointPrefetchDataSet1();
-
-        // query with to-many joint prefetches
-        SelectQuery q = new SelectQuery(Artist.class);
-        q.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(
-                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
-
-        final List<?> objects = context.performQuery(q);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                assertEquals(3, objects.size());
-
-                Iterator<?> it = objects.iterator();
-                while (it.hasNext()) {
-                    Artist a = (Artist) it.next();
-                    List<?> list = a.getPaintingArray();
-
-                    assertNotNull(list);
-                    assertFalse(((ValueHolder) list).isFault());
-
-                    Iterator<?> children = list.iterator();
-                    while (children.hasNext()) {
-                        Painting p = (Painting) children.next();
-                        assertEquals(PersistenceState.COMMITTED, p.getPersistenceState());
-                        // make sure properties are not null..
-                        assertNotNull(p.getPaintingTitle());
-                    }
-                }
-            }
-        });
-    }
-
-    public void testJointPrefetchToManyNonConflictingQualifier() throws Exception {
-        createJointPrefetchDataSet1();
-
-        // query with to-many joint prefetches and qualifier that doesn't match
-        // prefetch....
-        Expression qualifier = ExpressionFactory.matchExp(
-                Artist.ARTIST_NAME_PROPERTY,
-                "artist1");
-        SelectQuery q = new SelectQuery(Artist.class, qualifier);
-        q.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(
-                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
-
-        final List<?> objects = context.performQuery(q);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                assertEquals(1, objects.size());
-
-                Artist a = (Artist) objects.get(0);
-                List<?> list = a.getPaintingArray();
-
-                assertNotNull(list);
-                assertFalse(((ValueHolder) list).isFault());
-                assertEquals(2, list.size());
-
-                Iterator<?> children = list.iterator();
-                while (children.hasNext()) {
-                    Painting p = (Painting) children.next();
-                    assertEquals(PersistenceState.COMMITTED, p.getPersistenceState());
-                    // make sure properties are not null..
-                    assertNotNull(p.getPaintingTitle());
-                }
-
-                // assert no duplicates
-                Set s = new HashSet(list);
-                assertEquals(s.size(), list.size());
-            }
-        });
-    }
-
-    public void testJointPrefetchMultiStep() throws Exception {
-        createJointPrefetchDataSet2();
-
-        // query with to-many joint prefetches
-        SelectQuery q = new SelectQuery(Artist.class);
-        q
-                .addPrefetch(
-                        Artist.PAINTING_ARRAY_PROPERTY
-                                + "."
-                                + Painting.TO_GALLERY_PROPERTY)
-                .setSemantics(PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
-
-        final DataContext context = this.context;
-
-        // make sure phantomly prefetched objects are not deallocated
-        context.getObjectStore().objectMap = new HashMap<Object, Persistent>();
-
-        // sanity check...
-        DataObject g1 = (DataObject) context.getGraphManager().getNode(
-                new ObjectId("Gallery", Gallery.GALLERY_ID_PK_COLUMN, 33001));
-        assertNull(g1);
-
-        final List<?> objects = context.performQuery(q);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                assertEquals(3, objects.size());
-
-                Iterator<?> it = objects.iterator();
-                while (it.hasNext()) {
-                    Artist a = (Artist) it.next();
-                    ValueHolder list = (ValueHolder) a.getPaintingArray();
-
-                    assertNotNull(list);
-
-                    // intermediate relationship is not fetched...
-                    assertTrue(list.isFault());
-                }
-
-                // however both galleries must be in memory...
-                DataObject g1 = (DataObject) context.getGraphManager().getNode(
-                        new ObjectId("Gallery", Gallery.GALLERY_ID_PK_COLUMN, 33001));
-                assertNotNull(g1);
-                assertEquals(PersistenceState.COMMITTED, g1.getPersistenceState());
-                DataObject g2 = (DataObject) context.getGraphManager().getNode(
-                        new ObjectId("Gallery", Gallery.GALLERY_ID_PK_COLUMN, 33002));
-                assertNotNull(g2);
-                assertEquals(PersistenceState.COMMITTED, g2.getPersistenceState());
-            }
-        });
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/MiscTypesIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/MiscTypesIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/MiscTypesIT.java
new file mode 100644
index 0000000..3ed721f
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/MiscTypesIT.java
@@ -0,0 +1,186 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.access;
+
+import org.apache.cayenne.MockSerializable;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.testdo.testmap.ArraysEntity;
+import org.apache.cayenne.testdo.testmap.CharacterEntity;
+import org.apache.cayenne.testdo.testmap.SerializableEntity;
+import org.apache.cayenne.unit.UnitDbAdapter;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.lang.reflect.Array;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class MiscTypesIT extends ServerCase {
+
+    @Inject
+    private ObjectContext context;
+    
+    @Inject
+    private UnitDbAdapter accessStackAdapter;
+    
+    @Inject 
+    private DBHelper dbHelper;
+    
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        if(accessStackAdapter.supportsLobs()) {
+            dbHelper.deleteAll("SERIALIZABLE_ENTITY");
+        }
+        
+        dbHelper.deleteAll("ARRAYS_ENTITY");
+        dbHelper.deleteAll("CHARACTER_ENTITY");
+    }
+
+    public void testSerializable() throws Exception {
+        
+        // this test requires BLOB support
+        if(!accessStackAdapter.supportsLobs()) {
+            return;
+        }
+
+        SerializableEntity test = context
+                .newObject(SerializableEntity.class);
+
+        MockSerializable i = new MockSerializable("abc");
+        test.setSerializableField(i);
+        context.commitChanges();
+
+        SelectQuery q = new SelectQuery(SerializableEntity.class);
+        SerializableEntity testRead = (SerializableEntity) context.performQuery(q).get(0);
+        assertNotNull(testRead.getSerializableField());
+        assertEquals(i.getName(), testRead.getSerializableField().getName());
+
+        test.setSerializableField(null);
+        context.commitChanges();
+    }
+
+    public void testByteArray() {
+        ArraysEntity test = context.newObject(ArraysEntity.class);
+
+        byte[] a = new byte[] {
+                1, 2, 3
+        };
+        test.setByteArray(a);
+        context.commitChanges();
+
+        SelectQuery q = new SelectQuery(ArraysEntity.class);
+        ArraysEntity testRead = (ArraysEntity) context.performQuery(q).get(0);
+        assertNotNull(testRead.getByteArray());
+        assertArraysEqual(a, testRead.getByteArray());
+
+        test.setByteArray(null);
+        context.commitChanges();
+    }
+
+    public void testCharArray() {
+        ArraysEntity test = context.newObject(ArraysEntity.class);
+
+        char[] a = new char[] {
+                'x', 'y', 'z'
+        };
+        test.setCharArray(a);
+        context.commitChanges();
+
+        SelectQuery q = new SelectQuery(ArraysEntity.class);
+        ArraysEntity testRead = (ArraysEntity) context.performQuery(q).get(0);
+        assertNotNull(testRead.getCharArray());
+        assertArraysEqual(a, testRead.getCharArray());
+
+        test.setCharArray(null);
+        context.commitChanges();
+    }
+
+    public void testCharacterArray() {
+        ArraysEntity test = context.newObject(ArraysEntity.class);
+
+        Character[] a = new Character[] {
+                new Character('x'), new Character('y'), new Character('z')
+        };
+        test.setCharWrapperArray(a);
+        context.commitChanges();
+
+        SelectQuery q = new SelectQuery(ArraysEntity.class);
+        ArraysEntity testRead = (ArraysEntity) context.performQuery(q).get(0);
+        assertNotNull(testRead.getCharWrapperArray());
+        assertArraysEqual(a, testRead.getCharWrapperArray());
+
+        test.setCharWrapperArray(null);
+        context.commitChanges();
+    }
+    
+    public void testCharacter() {
+        CharacterEntity test = context.newObject(CharacterEntity.class);
+
+        test.setCharacterField(new Character('c'));
+        context.commitChanges();
+
+        SelectQuery q = new SelectQuery(CharacterEntity.class);
+        CharacterEntity testRead = (CharacterEntity) context.performQuery(q).get(0);
+        assertNotNull(testRead.getCharacterField());
+        assertEquals(new Character('c'), testRead.getCharacterField());
+
+        test.setCharacterField(null);
+        context.commitChanges();
+    }
+
+    public void testByteWrapperArray() {
+        ArraysEntity test = context.newObject(ArraysEntity.class);
+
+        Byte[] a = new Byte[] {
+                new Byte((byte) 1), new Byte((byte) 2), new Byte((byte) 3)
+        };
+        test.setByteWrapperArray(a);
+        context.commitChanges();
+
+        SelectQuery q = new SelectQuery(ArraysEntity.class);
+        ArraysEntity testRead = (ArraysEntity) context.performQuery(q).get(0);
+        assertNotNull(testRead.getByteWrapperArray());
+        assertArraysEqual(a, testRead.getByteWrapperArray());
+
+        test.setByteWrapperArray(null);
+        context.commitChanges();
+    }
+
+    private void assertArraysEqual(Object a1, Object a2) {
+
+        if (a1 == null && a2 == null) {
+            return;
+        }
+
+        if (a1 == null && a2 != null) {
+            fail("First array is null");
+        }
+
+        if (a2 == null && a1 != null) {
+            fail("Second array is null");
+        }
+
+        assertEquals(Array.getLength(a1), Array.getLength(a2));
+        for (int i = 0; i < Array.getLength(a1); i++) {
+            assertEquals("Difference at index " + i, Array.get(a1, i), Array.get(a2, i));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/MiscTypesTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/MiscTypesTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/MiscTypesTest.java
deleted file mode 100644
index 5c5e32d..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/MiscTypesTest.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-package org.apache.cayenne.access;
-
-import java.lang.reflect.Array;
-
-import org.apache.cayenne.MockSerializable;
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.testdo.testmap.ArraysEntity;
-import org.apache.cayenne.testdo.testmap.CharacterEntity;
-import org.apache.cayenne.testdo.testmap.SerializableEntity;
-import org.apache.cayenne.unit.UnitDbAdapter;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class MiscTypesTest extends ServerCase {
-
-    @Inject
-    private ObjectContext context;
-    
-    @Inject
-    private UnitDbAdapter accessStackAdapter;
-    
-    @Inject 
-    private DBHelper dbHelper;
-    
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        if(accessStackAdapter.supportsLobs()) {
-            dbHelper.deleteAll("SERIALIZABLE_ENTITY");
-        }
-        
-        dbHelper.deleteAll("ARRAYS_ENTITY");
-        dbHelper.deleteAll("CHARACTER_ENTITY");
-    }
-
-    public void testSerializable() throws Exception {
-        
-        // this test requires BLOB support
-        if(!accessStackAdapter.supportsLobs()) {
-            return;
-        }
-
-        SerializableEntity test = context
-                .newObject(SerializableEntity.class);
-
-        MockSerializable i = new MockSerializable("abc");
-        test.setSerializableField(i);
-        context.commitChanges();
-
-        SelectQuery q = new SelectQuery(SerializableEntity.class);
-        SerializableEntity testRead = (SerializableEntity) context.performQuery(q).get(0);
-        assertNotNull(testRead.getSerializableField());
-        assertEquals(i.getName(), testRead.getSerializableField().getName());
-
-        test.setSerializableField(null);
-        context.commitChanges();
-    }
-
-    public void testByteArray() {
-        ArraysEntity test = context.newObject(ArraysEntity.class);
-
-        byte[] a = new byte[] {
-                1, 2, 3
-        };
-        test.setByteArray(a);
-        context.commitChanges();
-
-        SelectQuery q = new SelectQuery(ArraysEntity.class);
-        ArraysEntity testRead = (ArraysEntity) context.performQuery(q).get(0);
-        assertNotNull(testRead.getByteArray());
-        assertArraysEqual(a, testRead.getByteArray());
-
-        test.setByteArray(null);
-        context.commitChanges();
-    }
-
-    public void testCharArray() {
-        ArraysEntity test = context.newObject(ArraysEntity.class);
-
-        char[] a = new char[] {
-                'x', 'y', 'z'
-        };
-        test.setCharArray(a);
-        context.commitChanges();
-
-        SelectQuery q = new SelectQuery(ArraysEntity.class);
-        ArraysEntity testRead = (ArraysEntity) context.performQuery(q).get(0);
-        assertNotNull(testRead.getCharArray());
-        assertArraysEqual(a, testRead.getCharArray());
-
-        test.setCharArray(null);
-        context.commitChanges();
-    }
-
-    public void testCharacterArray() {
-        ArraysEntity test = context.newObject(ArraysEntity.class);
-
-        Character[] a = new Character[] {
-                new Character('x'), new Character('y'), new Character('z')
-        };
-        test.setCharWrapperArray(a);
-        context.commitChanges();
-
-        SelectQuery q = new SelectQuery(ArraysEntity.class);
-        ArraysEntity testRead = (ArraysEntity) context.performQuery(q).get(0);
-        assertNotNull(testRead.getCharWrapperArray());
-        assertArraysEqual(a, testRead.getCharWrapperArray());
-
-        test.setCharWrapperArray(null);
-        context.commitChanges();
-    }
-    
-    public void testCharacter() {
-        CharacterEntity test = context.newObject(CharacterEntity.class);
-
-        test.setCharacterField(new Character('c'));
-        context.commitChanges();
-
-        SelectQuery q = new SelectQuery(CharacterEntity.class);
-        CharacterEntity testRead = (CharacterEntity) context.performQuery(q).get(0);
-        assertNotNull(testRead.getCharacterField());
-        assertEquals(new Character('c'), testRead.getCharacterField());
-
-        test.setCharacterField(null);
-        context.commitChanges();
-    }
-
-    public void testByteWrapperArray() {
-        ArraysEntity test = context.newObject(ArraysEntity.class);
-
-        Byte[] a = new Byte[] {
-                new Byte((byte) 1), new Byte((byte) 2), new Byte((byte) 3)
-        };
-        test.setByteWrapperArray(a);
-        context.commitChanges();
-
-        SelectQuery q = new SelectQuery(ArraysEntity.class);
-        ArraysEntity testRead = (ArraysEntity) context.performQuery(q).get(0);
-        assertNotNull(testRead.getByteWrapperArray());
-        assertArraysEqual(a, testRead.getByteWrapperArray());
-
-        test.setByteWrapperArray(null);
-        context.commitChanges();
-    }
-
-    private void assertArraysEqual(Object a1, Object a2) {
-
-        if (a1 == null && a2 == null) {
-            return;
-        }
-
-        if (a1 == null && a2 != null) {
-            fail("First array is null");
-        }
-
-        if (a2 == null && a1 != null) {
-            fail("Second array is null");
-        }
-
-        assertEquals(Array.getLength(a1), Array.getLength(a2));
-        for (int i = 0; i < Array.getLength(a1); i++) {
-            assertEquals("Difference at index " + i, Array.get(a1, i), Array.get(a2, i));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextLocalCacheIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextLocalCacheIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextLocalCacheIT.java
new file mode 100644
index 0000000..01bf924
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextLocalCacheIT.java
@@ -0,0 +1,77 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.access;
+
+import org.apache.cayenne.BaseContext;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.QueryCacheStrategy;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.util.List;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class NestedDataContextLocalCacheIT extends ServerCase {
+
+    @Inject
+    protected ServerRuntime runtime;
+    
+    @Inject
+    private DataContext context;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("PAINTING_INFO");
+        dbHelper.deleteAll("PAINTING");
+        dbHelper.deleteAll("ARTIST_EXHIBIT");
+        dbHelper.deleteAll("ARTIST_GROUP");
+        dbHelper.deleteAll("ARTIST");
+        dbHelper.deleteAll("EXHIBIT");
+        dbHelper.deleteAll("GALLERY");
+    }
+
+    public void testLocalCacheStaysLocal() {
+
+        SelectQuery query = new SelectQuery(Artist.class);
+        query.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
+
+        ObjectContext child1 = runtime.newContext(context);
+
+        assertNull(((BaseContext) child1).getQueryCache().get(
+                query.getMetaData(child1.getEntityResolver())));
+
+        assertNull(context.getQueryCache().get(
+                query.getMetaData(context.getEntityResolver())));
+
+        List<?> results = child1.performQuery(query);
+        assertSame(results, ((BaseContext) child1).getQueryCache().get(
+                query.getMetaData(child1.getEntityResolver())));
+
+        assertNull(context.getQueryCache().get(
+                query.getMetaData(context.getEntityResolver())));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextLocalCacheTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextLocalCacheTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextLocalCacheTest.java
deleted file mode 100644
index 2c385fc..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextLocalCacheTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-package org.apache.cayenne.access;
-
-import java.util.List;
-
-import org.apache.cayenne.BaseContext;
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.configuration.server.ServerRuntime;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.QueryCacheStrategy;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.testdo.testmap.Artist;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class NestedDataContextLocalCacheTest extends ServerCase {
-
-    @Inject
-    protected ServerRuntime runtime;
-    
-    @Inject
-    private DataContext context;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("PAINTING_INFO");
-        dbHelper.deleteAll("PAINTING");
-        dbHelper.deleteAll("ARTIST_EXHIBIT");
-        dbHelper.deleteAll("ARTIST_GROUP");
-        dbHelper.deleteAll("ARTIST");
-        dbHelper.deleteAll("EXHIBIT");
-        dbHelper.deleteAll("GALLERY");
-    }
-
-    public void testLocalCacheStaysLocal() {
-
-        SelectQuery query = new SelectQuery(Artist.class);
-        query.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
-
-        ObjectContext child1 = runtime.newContext(context);
-
-        assertNull(((BaseContext) child1).getQueryCache().get(
-                query.getMetaData(child1.getEntityResolver())));
-
-        assertNull(context.getQueryCache().get(
-                query.getMetaData(context.getEntityResolver())));
-
-        List<?> results = child1.performQuery(query);
-        assertSame(results, ((BaseContext) child1).getQueryCache().get(
-                query.getMetaData(child1.getEntityResolver())));
-
-        assertNull(context.getQueryCache().get(
-                query.getMetaData(context.getEntityResolver())));
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextParentEventsIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextParentEventsIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextParentEventsIT.java
new file mode 100644
index 0000000..fa87bc8
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextParentEventsIT.java
@@ -0,0 +1,61 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.access;
+
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.test.parallel.ParallelTestContainer;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class NestedDataContextParentEventsIT extends ServerCase {
+
+    @Inject
+    protected ServerRuntime runtime;
+
+    @Inject
+    private DataContext context;
+
+    public void testParentUpdatedId() throws Exception {
+        ObjectContext child1 = runtime.newContext(context);
+
+        final Artist ac = child1.newObject(Artist.class);
+        ac.setArtistName("X");
+        child1.commitChangesToParent();
+
+        final Artist ap = (Artist) context.getGraphManager().getNode(ac.getObjectId());
+        assertNotNull(ap);
+
+        assertTrue(ap.getObjectId().isTemporary());
+        context.commitChanges();
+
+        new ParallelTestContainer() {
+
+            @Override
+            protected void assertResult() throws Exception {
+                assertFalse(ap.getObjectId().isTemporary());
+                assertEquals(ap.getObjectId(), ac.getObjectId());
+            }
+        }.runTest(1000);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextParentEventsTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextParentEventsTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextParentEventsTest.java
deleted file mode 100644
index a78b132..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextParentEventsTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.access;
-
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.configuration.server.ServerRuntime;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.test.parallel.ParallelTestContainer;
-import org.apache.cayenne.testdo.testmap.Artist;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class NestedDataContextParentEventsTest extends ServerCase {
-
-    @Inject
-    protected ServerRuntime runtime;
-
-    @Inject
-    private DataContext context;
-
-    public void testParentUpdatedId() throws Exception {
-        ObjectContext child1 = runtime.newContext(context);
-
-        final Artist ac = child1.newObject(Artist.class);
-        ac.setArtistName("X");
-        child1.commitChangesToParent();
-
-        final Artist ap = (Artist) context.getGraphManager().getNode(ac.getObjectId());
-        assertNotNull(ap);
-
-        assertTrue(ap.getObjectId().isTemporary());
-        context.commitChanges();
-
-        new ParallelTestContainer() {
-
-            @Override
-            protected void assertResult() throws Exception {
-                assertFalse(ap.getObjectId().isTemporary());
-                assertEquals(ap.getObjectId(), ac.getObjectId());
-            }
-        }.runTest(1000);
-    }
-}