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:12 UTC

[24/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/DeleteRulesTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DeleteRulesTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DeleteRulesTest.java
deleted file mode 100644
index def09fe..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/DeleteRulesTest.java
+++ /dev/null
@@ -1,374 +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.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.apache.cayenne.DeleteDenyException;
-import org.apache.cayenne.PersistenceState;
-import org.apache.cayenne.access.ObjectDiff.ArcOperation;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.graph.NodeDiff;
-import org.apache.cayenne.map.DeleteRule;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.map.ObjRelationship;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.testdo.relationship.DeleteRuleFlatA;
-import org.apache.cayenne.testdo.relationship.DeleteRuleFlatB;
-import org.apache.cayenne.testdo.relationship.DeleteRuleTest1;
-import org.apache.cayenne.testdo.relationship.DeleteRuleTest2;
-import org.apache.cayenne.testdo.relationship.DeleteRuleTest3;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.RELATIONSHIPS_PROJECT)
-public class DeleteRulesTest extends ServerCase {
-
-    @Inject
-    private DataContext context;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("DELETE_RULE_TEST3");
-        dbHelper.deleteAll("DELETE_RULE_TEST1");
-        dbHelper.deleteAll("DELETE_RULE_TEST2");
-        dbHelper.deleteAll("DELETE_RULE_JOIN");
-        dbHelper.deleteAll("DELETE_RULE_FLATB");
-        dbHelper.deleteAll("DELETE_RULE_FLATA");
-    }
-
-    public void testDenyToOne() {
-
-        DeleteRuleTest1 test1 = context.newObject(DeleteRuleTest1.class);
-        DeleteRuleTest2 test2 = context.newObject(DeleteRuleTest2.class);
-        test1.setTest2(test2);
-        context.commitChanges();
-
-        try {
-            context.deleteObjects(test1);
-            fail("Should have thrown an exception");
-        } catch (Exception e) {
-            // GOOD!
-        }
-        context.commitChanges();
-
-    }
-
-    public void testNoActionToOne() {
-        DeleteRuleTest2 test2 = context.newObject(DeleteRuleTest2.class);
-        DeleteRuleTest3 test3 = context.newObject(DeleteRuleTest3.class);
-        test3.setToDeleteRuleTest2(test2);
-        context.commitChanges();
-
-        // must go on without exceptions...
-        context.deleteObjects(test3);
-        context.commitChanges();
-    }
-
-    public void testNoActionToMany() {
-        DeleteRuleTest2 test2 = context.newObject(DeleteRuleTest2.class);
-        DeleteRuleTest3 test3 = context.newObject(DeleteRuleTest3.class);
-        test3.setToDeleteRuleTest2(test2);
-        context.commitChanges();
-
-        // must go on without exceptions...
-        context.deleteObjects(test2);
-
-        // don't commit, since this will cause a constraint exception
-    }
-
-    public void testNoActionFlattened() {
-        // temporarily set delete rule to NOACTION...
-        int oldRule = changeDeleteRule(DeleteRule.NO_ACTION);
-
-        try {
-            DeleteRuleFlatA a = context.newObject(DeleteRuleFlatA.class);
-            DeleteRuleFlatB b = context.newObject(DeleteRuleFlatB.class);
-
-            a.addToFlatB(b);
-            context.commitChanges();
-
-            // must go on without exceptions...
-            context.deleteObjects(a);
-
-            // assert that join is deleted
-            assertJoinDeleted(a, b);
-            assertEquals(PersistenceState.DELETED, a.getPersistenceState());
-            assertEquals(PersistenceState.COMMITTED, b.getPersistenceState());
-            assertTrue(b.getUntitledRel().contains(a));
-            context.commitChanges();
-
-        } finally {
-            changeDeleteRule(oldRule);
-        }
-    }
-
-    public void testNoActionFlattenedNoReverse() {
-        // temporarily set delete rule to NOACTION...
-        int oldRule = changeDeleteRule(DeleteRule.NO_ACTION);
-        ObjRelationship reverse = unsetReverse();
-
-        try {
-            DeleteRuleFlatA a = context.newObject(DeleteRuleFlatA.class);
-            DeleteRuleFlatB b = context.newObject(DeleteRuleFlatB.class);
-
-            a.addToFlatB(b);
-            context.commitChanges();
-
-            // must go on without exceptions...
-            context.deleteObjects(a);
-
-            // assert that join is deleted
-            assertJoinDeleted(a, b);
-            assertEquals(PersistenceState.DELETED, a.getPersistenceState());
-            assertEquals(PersistenceState.COMMITTED, b.getPersistenceState());
-            context.commitChanges();
-        } finally {
-            changeDeleteRule(oldRule);
-            restoreReverse(reverse);
-        }
-    }
-
-    public void testCascadeFlattened() {
-        // temporarily set delete rule to CASCADE...
-        int oldRule = changeDeleteRule(DeleteRule.CASCADE);
-
-        try {
-            DeleteRuleFlatA a = context.newObject(DeleteRuleFlatA.class);
-            DeleteRuleFlatB b = context.newObject(DeleteRuleFlatB.class);
-            a.addToFlatB(b);
-            context.commitChanges();
-
-            // must go on without exceptions...
-            context.deleteObjects(a);
-
-            // assert that join is deleted
-            assertJoinDeleted(a, b);
-            context.commitChanges();
-
-            assertEquals(PersistenceState.TRANSIENT, a.getPersistenceState());
-            assertEquals(PersistenceState.TRANSIENT, b.getPersistenceState());
-        } finally {
-            changeDeleteRule(oldRule);
-        }
-    }
-
-    public void testCascadeFlattenedNoReverse() {
-        // temporarily set delete rule to CASCADE...
-        int oldRule = changeDeleteRule(DeleteRule.CASCADE);
-        ObjRelationship reverse = unsetReverse();
-
-        try {
-            DeleteRuleFlatA a = context.newObject(DeleteRuleFlatA.class);
-            DeleteRuleFlatB b = context.newObject(DeleteRuleFlatB.class);
-            a.addToFlatB(b);
-            context.commitChanges();
-
-            // must go on without exceptions...
-            context.deleteObjects(a);
-
-            // assert that join is deleted
-            assertJoinDeleted(a, b);
-            context.commitChanges();
-            assertEquals(PersistenceState.TRANSIENT, a.getPersistenceState());
-            assertEquals(PersistenceState.TRANSIENT, b.getPersistenceState());
-        } finally {
-            changeDeleteRule(oldRule);
-            restoreReverse(reverse);
-        }
-    }
-
-    public void testNullifyFlattened() {
-        // temporarily set delete rule to NULLIFY...
-        int oldRule = changeDeleteRule(DeleteRule.NULLIFY);
-
-        try {
-            DeleteRuleFlatA a = context.newObject(DeleteRuleFlatA.class);
-            DeleteRuleFlatB b = context.newObject(DeleteRuleFlatB.class);
-            a.addToFlatB(b);
-            context.commitChanges();
-
-            // must go on without exceptions...
-            context.deleteObjects(a);
-
-            // assert that join is deleted
-            assertJoinDeleted(a, b);
-            assertEquals(PersistenceState.DELETED, a.getPersistenceState());
-            assertEquals(PersistenceState.MODIFIED, b.getPersistenceState());
-            assertFalse(b.getUntitledRel().contains(a));
-            context.commitChanges();
-        } finally {
-            changeDeleteRule(oldRule);
-        }
-    }
-
-    public void testNullifyFlattenedNoReverse() {
-        // temporarily set delete rule to NULLIFY...
-        int oldRule = changeDeleteRule(DeleteRule.NULLIFY);
-        ObjRelationship reverse = unsetReverse();
-
-        try {
-            DeleteRuleFlatA a = context.newObject(DeleteRuleFlatA.class);
-            DeleteRuleFlatB b = context.newObject(DeleteRuleFlatB.class);
-            a.addToFlatB(b);
-            context.commitChanges();
-
-            // must go on without exceptions...
-            context.deleteObjects(a);
-
-            // assert that join is deleted
-            assertJoinDeleted(a, b);
-            assertEquals(PersistenceState.DELETED, a.getPersistenceState());
-            assertEquals(PersistenceState.COMMITTED, b.getPersistenceState());
-            context.commitChanges();
-        } finally {
-            changeDeleteRule(oldRule);
-            restoreReverse(reverse);
-        }
-    }
-
-    public void testDenyFlattened() {
-        // temporarily set delete rule to DENY...
-        int oldRule = changeDeleteRule(DeleteRule.DENY);
-
-        try {
-            DeleteRuleFlatA a = context.newObject(DeleteRuleFlatA.class);
-            DeleteRuleFlatB b = context.newObject(DeleteRuleFlatB.class);
-            a.addToFlatB(b);
-            context.commitChanges();
-
-            try {
-                context.deleteObjects(a);
-                fail("Must have thrown a deny exception..");
-            } catch (DeleteDenyException ex) {
-                // expected... but check further
-                assertJoinNotDeleted(a, b);
-            }
-        } finally {
-            changeDeleteRule(oldRule);
-        }
-    }
-
-    public void testDenyFlattenedNoReverse() {
-        // temporarily set delete rule to DENY...
-        int oldRule = changeDeleteRule(DeleteRule.DENY);
-        ObjRelationship reverse = unsetReverse();
-
-        try {
-            DeleteRuleFlatA a = context.newObject(DeleteRuleFlatA.class);
-            DeleteRuleFlatB b = context.newObject(DeleteRuleFlatB.class);
-            a.addToFlatB(b);
-            context.commitChanges();
-
-            try {
-                context.deleteObjects(a);
-                fail("Must have thrown a deny exception..");
-            } catch (DeleteDenyException ex) {
-                // expected... but check further
-                assertJoinNotDeleted(a, b);
-            }
-        } finally {
-            changeDeleteRule(oldRule);
-            restoreReverse(reverse);
-        }
-    }
-
-    private int changeDeleteRule(int deleteRule) {
-        ObjEntity entity = context.getEntityResolver().getObjEntity(DeleteRuleFlatA.class);
-
-        ObjRelationship relationship = entity.getRelationship(DeleteRuleFlatA.FLAT_B_PROPERTY);
-        int oldRule = relationship.getDeleteRule();
-        relationship.setDeleteRule(deleteRule);
-        return oldRule;
-    }
-
-    private ObjRelationship unsetReverse() {
-        ObjEntity entity = context.getEntityResolver().getObjEntity(DeleteRuleFlatA.class);
-
-        ObjRelationship relationship = entity.getRelationship(DeleteRuleFlatA.FLAT_B_PROPERTY);
-        ObjRelationship reverse = relationship.getReverseRelationship();
-
-        if (reverse != null) {
-            reverse.getSourceEntity().removeRelationship(reverse.getName());
-            context.getEntityResolver().getClassDescriptorMap().removeDescriptor("DeleteRuleFlatA");
-            context.getEntityResolver().getClassDescriptorMap().removeDescriptor("DeleteRuleFlatB");
-        }
-
-        return reverse;
-    }
-
-    private void restoreReverse(ObjRelationship reverse) {
-        ObjEntity entity = context.getEntityResolver().getObjEntity(DeleteRuleFlatA.class);
-
-        ObjRelationship relationship = entity.getRelationship(DeleteRuleFlatA.FLAT_B_PROPERTY);
-        relationship.getTargetEntity().addRelationship(reverse);
-        context.getEntityResolver().getClassDescriptorMap().removeDescriptor("DeleteRuleFlatA");
-        context.getEntityResolver().getClassDescriptorMap().removeDescriptor("DeleteRuleFlatB");
-    }
-
-    private void assertJoinDeleted(DeleteRuleFlatA a, DeleteRuleFlatB b) {
-
-        ObjectDiff changes = context.getObjectStore().changes.get(a.getObjectId());
-
-        assertNotNull(changes);
-        Collection<NodeDiff> diffs = new ArrayList<NodeDiff>();
-        changes.appendDiffs(diffs);
-        Iterator<?> it = diffs.iterator();
-        while (it.hasNext()) {
-            Object diff = it.next();
-            if (diff instanceof ArcOperation) {
-                ArcOperation arcDelete = (ArcOperation) diff;
-                if (arcDelete.getNodeId().equals(a.getObjectId())
-                        && arcDelete.getTargetNodeId().equals(b.getObjectId())
-                        && arcDelete.getArcId().equals(DeleteRuleFlatA.FLAT_B_PROPERTY) && arcDelete.isDelete()) {
-                    return;
-                }
-            }
-        }
-
-        fail("Join was not deleted for flattened relationship");
-    }
-
-    private void assertJoinNotDeleted(DeleteRuleFlatA a, DeleteRuleFlatB b) {
-        ObjectDiff changes = context.getObjectStore().changes.get(a.getObjectId());
-
-        if (changes != null) {
-            Collection<NodeDiff> diffs = new ArrayList<NodeDiff>();
-            changes.appendDiffs(diffs);
-            Iterator<?> it = diffs.iterator();
-            while (it.hasNext()) {
-                Object diff = it.next();
-                if (diff instanceof ArcOperation) {
-                    ArcOperation arcDelete = (ArcOperation) diff;
-                    if (arcDelete.getNodeId().equals(a.getObjectId())
-                            && arcDelete.getTargetNodeId().equals(b.getObjectId())
-                            && arcDelete.getArcId().equals(DeleteRuleFlatA.FLAT_B_PROPERTY) && !arcDelete.isDelete()) {
-                        fail("Join was  deleted for flattened relationship");
-                    }
-                }
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/EmbeddingIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/EmbeddingIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/EmbeddingIT.java
new file mode 100644
index 0000000..8e9a3db
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/EmbeddingIT.java
@@ -0,0 +1,179 @@
+/*****************************************************************
+ *   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.Cayenne;
+import org.apache.cayenne.DataRow;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.PersistenceState;
+import org.apache.cayenne.di.Inject;
+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.embeddable.EmbedEntity1;
+import org.apache.cayenne.testdo.embeddable.Embeddable1;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.util.List;
+
+@UseServerRuntime(ServerCase.DEFAULT_PROJECT)
+public class EmbeddingIT extends ServerCase {
+    
+    @Inject
+    protected ObjectContext context;
+    
+    @Inject
+    protected DBHelper dbHelper;
+    
+    protected TableHelper tEmbedEntity1;
+    
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("EMBED_ENTITY1");
+        
+        tEmbedEntity1 = new TableHelper(dbHelper, "EMBED_ENTITY1");
+        tEmbedEntity1.setColumns("ID", "NAME", "EMBEDDED10", "EMBEDDED20", "EMBEDDED30", "EMBEDDED40");
+    }
+    
+    protected void createSelectDataSet() throws Exception {
+        tEmbedEntity1.delete().execute();
+        tEmbedEntity1.insert(1, "n1", "e1", "e2", "e3", "e4");
+        tEmbedEntity1.insert(2, "n2", "ex1", "ex2", "ex3", "ex4");
+    }
+    
+    protected void createUpdateDataSet() throws Exception {
+        tEmbedEntity1.delete().execute();
+        tEmbedEntity1.insert(1, "n1", "e1", "e2", "e3", "e4");
+    }
+
+    public void testSelect() throws Exception {
+        createSelectDataSet();
+
+        SelectQuery query = new SelectQuery(EmbedEntity1.class);
+        query.addOrdering(EmbedEntity1.NAME_PROPERTY, SortOrder.ASCENDING);
+
+        List<?> results = context.performQuery(query);
+        assertEquals(2, results.size());
+
+        EmbedEntity1 o1 = (EmbedEntity1) results.get(0);
+
+        assertEquals("n1", o1.getName());
+        Embeddable1 e11 = o1.getEmbedded1();
+        Embeddable1 e12 = o1.getEmbedded2();
+
+        assertNotNull(e11);
+        assertNotNull(e12);
+        assertEquals("e1", e11.getEmbedded10());
+        assertEquals("e2", e11.getEmbedded20());
+        assertEquals("e3", e12.getEmbedded10());
+        assertEquals("e4", e12.getEmbedded20());
+
+        EmbedEntity1 o2 = (EmbedEntity1) results.get(1);
+
+        assertEquals("n2", o2.getName());
+        Embeddable1 e21 = o2.getEmbedded1();
+        Embeddable1 e22 = o2.getEmbedded2();
+
+        assertNotNull(e21);
+        assertNotNull(e22);
+        assertEquals("ex1", e21.getEmbedded10());
+        assertEquals("ex2", e21.getEmbedded20());
+        assertEquals("ex3", e22.getEmbedded10());
+        assertEquals("ex4", e22.getEmbedded20());
+    }
+
+    public void testInsert() throws Exception {
+
+        EmbedEntity1 o1 = context.newObject(EmbedEntity1.class);
+        o1.setName("NAME");
+
+        Embeddable1 e1 = new Embeddable1();
+
+        // init before the embeddable was set on an owning object
+        e1.setEmbedded10("E11");
+        e1.setEmbedded20("E12");
+        o1.setEmbedded1(e1);
+
+        Embeddable1 e2 = new Embeddable1();
+        o1.setEmbedded2(e2);
+
+        // init after it was set on the owning object
+        e2.setEmbedded10("E21");
+        e2.setEmbedded20("E22");
+
+        context.commitChanges();
+
+        SelectQuery query = new SelectQuery(EmbedEntity1.class);
+        query.setFetchingDataRows(true);
+        DataRow row = (DataRow) Cayenne.objectForQuery(context, query);
+        assertNotNull(row);
+        assertEquals("E11", row.get("EMBEDDED10"));
+        assertEquals("E12", row.get("EMBEDDED20"));
+        assertEquals("E21", row.get("EMBEDDED30"));
+        assertEquals("E22", row.get("EMBEDDED40"));
+    }
+
+    public void testUpdateEmbeddedProperties() throws Exception {
+        createUpdateDataSet();
+
+        SelectQuery query = new SelectQuery(EmbedEntity1.class);
+        query.addOrdering(EmbedEntity1.NAME_PROPERTY, SortOrder.ASCENDING);
+
+        List<?> results = context.performQuery(query);
+        EmbedEntity1 o1 = (EmbedEntity1) results.get(0);
+
+        Embeddable1 e11 = o1.getEmbedded1();
+        e11.setEmbedded10("x1");
+
+        assertEquals(PersistenceState.MODIFIED, o1.getPersistenceState());
+
+        context.commitChanges();
+        SelectQuery query1 = new SelectQuery(EmbedEntity1.class);
+        query1.setFetchingDataRows(true);
+        DataRow row = (DataRow) Cayenne.objectForQuery(context, query1);
+        assertNotNull(row);
+        assertEquals("x1", row.get("EMBEDDED10"));
+    }
+
+    public void testUpdateEmbedded() throws Exception {
+        createUpdateDataSet();
+
+        SelectQuery query = new SelectQuery(EmbedEntity1.class);
+        query.addOrdering(EmbedEntity1.NAME_PROPERTY, SortOrder.ASCENDING);
+
+        List<?> results = context.performQuery(query);
+        EmbedEntity1 o1 = (EmbedEntity1) results.get(0);
+
+        Embeddable1 e11 = new Embeddable1();
+        e11.setEmbedded10("x1");
+        e11.setEmbedded20("x2");
+        o1.setEmbedded1(e11);
+
+        assertEquals(PersistenceState.MODIFIED, o1.getPersistenceState());
+
+        context.commitChanges();
+        SelectQuery query1 = new SelectQuery(EmbedEntity1.class);
+        query1.setFetchingDataRows(true);
+        DataRow row = (DataRow) Cayenne.objectForQuery(context, query1);
+        assertNotNull(row);
+        assertEquals("x1", row.get("EMBEDDED10"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/EmbeddingTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/EmbeddingTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/EmbeddingTest.java
deleted file mode 100644
index 65e3d66..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/EmbeddingTest.java
+++ /dev/null
@@ -1,179 +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.DataRow;
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.PersistenceState;
-import org.apache.cayenne.di.Inject;
-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.embeddable.EmbedEntity1;
-import org.apache.cayenne.testdo.embeddable.Embeddable1;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.DEFAULT_PROJECT)
-public class EmbeddingTest extends ServerCase {
-    
-    @Inject
-    protected ObjectContext context;
-    
-    @Inject
-    protected DBHelper dbHelper;
-    
-    protected TableHelper tEmbedEntity1;
-    
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("EMBED_ENTITY1");
-        
-        tEmbedEntity1 = new TableHelper(dbHelper, "EMBED_ENTITY1");
-        tEmbedEntity1.setColumns("ID", "NAME", "EMBEDDED10", "EMBEDDED20", "EMBEDDED30", "EMBEDDED40");
-    }
-    
-    protected void createSelectDataSet() throws Exception {
-        tEmbedEntity1.delete().execute();
-        tEmbedEntity1.insert(1, "n1", "e1", "e2", "e3", "e4");
-        tEmbedEntity1.insert(2, "n2", "ex1", "ex2", "ex3", "ex4");
-    }
-    
-    protected void createUpdateDataSet() throws Exception {
-        tEmbedEntity1.delete().execute();
-        tEmbedEntity1.insert(1, "n1", "e1", "e2", "e3", "e4");
-    }
-
-    public void testSelect() throws Exception {
-        createSelectDataSet();
-
-        SelectQuery query = new SelectQuery(EmbedEntity1.class);
-        query.addOrdering(EmbedEntity1.NAME_PROPERTY, SortOrder.ASCENDING);
-
-        List<?> results = context.performQuery(query);
-        assertEquals(2, results.size());
-
-        EmbedEntity1 o1 = (EmbedEntity1) results.get(0);
-
-        assertEquals("n1", o1.getName());
-        Embeddable1 e11 = o1.getEmbedded1();
-        Embeddable1 e12 = o1.getEmbedded2();
-
-        assertNotNull(e11);
-        assertNotNull(e12);
-        assertEquals("e1", e11.getEmbedded10());
-        assertEquals("e2", e11.getEmbedded20());
-        assertEquals("e3", e12.getEmbedded10());
-        assertEquals("e4", e12.getEmbedded20());
-
-        EmbedEntity1 o2 = (EmbedEntity1) results.get(1);
-
-        assertEquals("n2", o2.getName());
-        Embeddable1 e21 = o2.getEmbedded1();
-        Embeddable1 e22 = o2.getEmbedded2();
-
-        assertNotNull(e21);
-        assertNotNull(e22);
-        assertEquals("ex1", e21.getEmbedded10());
-        assertEquals("ex2", e21.getEmbedded20());
-        assertEquals("ex3", e22.getEmbedded10());
-        assertEquals("ex4", e22.getEmbedded20());
-    }
-
-    public void testInsert() throws Exception {
-
-        EmbedEntity1 o1 = context.newObject(EmbedEntity1.class);
-        o1.setName("NAME");
-
-        Embeddable1 e1 = new Embeddable1();
-
-        // init before the embeddable was set on an owning object
-        e1.setEmbedded10("E11");
-        e1.setEmbedded20("E12");
-        o1.setEmbedded1(e1);
-
-        Embeddable1 e2 = new Embeddable1();
-        o1.setEmbedded2(e2);
-
-        // init after it was set on the owning object
-        e2.setEmbedded10("E21");
-        e2.setEmbedded20("E22");
-
-        context.commitChanges();
-
-        SelectQuery query = new SelectQuery(EmbedEntity1.class);
-        query.setFetchingDataRows(true);
-        DataRow row = (DataRow) Cayenne.objectForQuery(context, query);
-        assertNotNull(row);
-        assertEquals("E11", row.get("EMBEDDED10"));
-        assertEquals("E12", row.get("EMBEDDED20"));
-        assertEquals("E21", row.get("EMBEDDED30"));
-        assertEquals("E22", row.get("EMBEDDED40"));
-    }
-
-    public void testUpdateEmbeddedProperties() throws Exception {
-        createUpdateDataSet();
-
-        SelectQuery query = new SelectQuery(EmbedEntity1.class);
-        query.addOrdering(EmbedEntity1.NAME_PROPERTY, SortOrder.ASCENDING);
-
-        List<?> results = context.performQuery(query);
-        EmbedEntity1 o1 = (EmbedEntity1) results.get(0);
-
-        Embeddable1 e11 = o1.getEmbedded1();
-        e11.setEmbedded10("x1");
-
-        assertEquals(PersistenceState.MODIFIED, o1.getPersistenceState());
-
-        context.commitChanges();
-        SelectQuery query1 = new SelectQuery(EmbedEntity1.class);
-        query1.setFetchingDataRows(true);
-        DataRow row = (DataRow) Cayenne.objectForQuery(context, query1);
-        assertNotNull(row);
-        assertEquals("x1", row.get("EMBEDDED10"));
-    }
-
-    public void testUpdateEmbedded() throws Exception {
-        createUpdateDataSet();
-
-        SelectQuery query = new SelectQuery(EmbedEntity1.class);
-        query.addOrdering(EmbedEntity1.NAME_PROPERTY, SortOrder.ASCENDING);
-
-        List<?> results = context.performQuery(query);
-        EmbedEntity1 o1 = (EmbedEntity1) results.get(0);
-
-        Embeddable1 e11 = new Embeddable1();
-        e11.setEmbedded10("x1");
-        e11.setEmbedded20("x2");
-        o1.setEmbedded1(e11);
-
-        assertEquals(PersistenceState.MODIFIED, o1.getPersistenceState());
-
-        context.commitChanges();
-        SelectQuery query1 = new SelectQuery(EmbedEntity1.class);
-        query1.setFetchingDataRows(true);
-        DataRow row = (DataRow) Cayenne.objectForQuery(context, query1);
-        assertNotNull(row);
-        assertEquals("x1", row.get("EMBEDDED10"));
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/EnumIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/EnumIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/EnumIT.java
new file mode 100644
index 0000000..45e15fd
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/EnumIT.java
@@ -0,0 +1,89 @@
+/*****************************************************************
+ *   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.Cayenne;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.query.CapsStrategy;
+import org.apache.cayenne.query.SQLTemplate;
+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.Enum1;
+import org.apache.cayenne.testdo.testmap.EnumEntity;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class EnumIT extends ServerCase {
+
+    @Inject
+    private ObjectContext context;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("ENUM_ENTITY");
+
+    }
+
+    private void createDataSet() throws Exception {
+        TableHelper tEnumEntity = new TableHelper(dbHelper, "ENUM_ENTITY");
+        tEnumEntity.setColumns("ID", "ENUM_ATTRIBUTE");
+
+        tEnumEntity.insert(1, "two");
+        tEnumEntity.insert(2, "one");
+    }
+
+    public void testInsert() {
+        EnumEntity e = context.newObject(EnumEntity.class);
+        e.setEnumAttribute(Enum1.one);
+        context.commitChanges();
+    }
+
+    public void testSelectQuery() throws Exception {
+        createDataSet();
+
+        SelectQuery q = new SelectQuery(EnumEntity.class);
+        q.andQualifier(ExpressionFactory.matchExp(
+                EnumEntity.ENUM_ATTRIBUTE_PROPERTY,
+                Enum1.one));
+
+        EnumEntity e = (EnumEntity) Cayenne.objectForQuery(context, q);
+        assertNotNull(e);
+        assertSame(Enum1.one, e.getEnumAttribute());
+    }
+
+    public void testSQLTemplate() throws Exception {
+        createDataSet();
+
+        SQLTemplate q = new SQLTemplate(
+                EnumEntity.class,
+                "SELECT * FROM ENUM_ENTITY WHERE ENUM_ATTRIBUTE = 'one'");
+        q.setColumnNamesCapitalization(CapsStrategy.UPPER);
+
+        EnumEntity e = (EnumEntity) Cayenne.objectForQuery(context, q);
+        assertNotNull(e);
+        assertSame(Enum1.one, e.getEnumAttribute());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/EnumTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/EnumTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/EnumTest.java
deleted file mode 100644
index cce7090..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/EnumTest.java
+++ /dev/null
@@ -1,89 +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.Cayenne;
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.ExpressionFactory;
-import org.apache.cayenne.query.CapsStrategy;
-import org.apache.cayenne.query.SQLTemplate;
-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.Enum1;
-import org.apache.cayenne.testdo.testmap.EnumEntity;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class EnumTest extends ServerCase {
-
-    @Inject
-    private ObjectContext context;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("ENUM_ENTITY");
-
-    }
-
-    private void createDataSet() throws Exception {
-        TableHelper tEnumEntity = new TableHelper(dbHelper, "ENUM_ENTITY");
-        tEnumEntity.setColumns("ID", "ENUM_ATTRIBUTE");
-
-        tEnumEntity.insert(1, "two");
-        tEnumEntity.insert(2, "one");
-    }
-
-    public void testInsert() {
-        EnumEntity e = context.newObject(EnumEntity.class);
-        e.setEnumAttribute(Enum1.one);
-        context.commitChanges();
-    }
-
-    public void testSelectQuery() throws Exception {
-        createDataSet();
-
-        SelectQuery q = new SelectQuery(EnumEntity.class);
-        q.andQualifier(ExpressionFactory.matchExp(
-                EnumEntity.ENUM_ATTRIBUTE_PROPERTY,
-                Enum1.one));
-
-        EnumEntity e = (EnumEntity) Cayenne.objectForQuery(context, q);
-        assertNotNull(e);
-        assertSame(Enum1.one, e.getEnumAttribute());
-    }
-
-    public void testSQLTemplate() throws Exception {
-        createDataSet();
-
-        SQLTemplate q = new SQLTemplate(
-                EnumEntity.class,
-                "SELECT * FROM ENUM_ENTITY WHERE ENUM_ATTRIBUTE = 'one'");
-        q.setColumnNamesCapitalization(CapsStrategy.UPPER);
-
-        EnumEntity e = (EnumEntity) Cayenne.objectForQuery(context, q);
-        assertNotNull(e);
-        assertSame(Enum1.one, e.getEnumAttribute());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedArcKeyIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedArcKeyIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedArcKeyIT.java
new file mode 100644
index 0000000..96c0191
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedArcKeyIT.java
@@ -0,0 +1,89 @@
+/*****************************************************************
+ *   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.ObjectId;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.testdo.relationship.FlattenedTest1;
+import org.apache.cayenne.testdo.relationship.FlattenedTest3;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+@UseServerRuntime(ServerCase.RELATIONSHIPS_PROJECT)
+public class FlattenedArcKeyIT extends ServerCase {
+
+    @Inject
+    private EntityResolver entityResolver;
+
+    public void testAttributes() {
+        ObjectId src = new ObjectId("X");
+        ObjectId target = new ObjectId("Y");
+        ObjRelationship r1 = entityResolver.getObjEntity(FlattenedTest3.class).getRelationship(
+                FlattenedTest3.TO_FT1_PROPERTY);
+
+        FlattenedArcKey update = new FlattenedArcKey(src, target, r1);
+
+        assertSame(src, update.id1.getSourceId());
+        assertSame(target, update.id2.getSourceId());
+        assertSame(r1, update.relationship);
+    }
+
+    public void testHashCode() {
+        ObjectId src = new ObjectId("X");
+        ObjectId target = new ObjectId("Y");
+        ObjRelationship r1 = entityResolver.getObjEntity(FlattenedTest3.class).getRelationship(
+                FlattenedTest3.TO_FT1_PROPERTY);
+
+        FlattenedArcKey update = new FlattenedArcKey(src, target, r1);
+        FlattenedArcKey update1 = new FlattenedArcKey(target, src, r1.getReverseRelationship());
+
+        ObjRelationship r3 = entityResolver.getObjEntity(FlattenedTest1.class).getRelationship(
+                FlattenedTest1.FT3OVER_COMPLEX_PROPERTY);
+
+        FlattenedArcKey update2 = new FlattenedArcKey(target, src, r3);
+
+        int h = update.hashCode();
+        int h1 = update1.hashCode();
+        int h2 = update2.hashCode();
+        assertTrue(h == h1);
+        assertTrue(h == update.hashCode());
+        assertFalse(h == h2);
+    }
+
+    public void testEquals() {
+        ObjectId src = new ObjectId("X");
+        ObjectId target = new ObjectId("Y");
+        ObjRelationship r1 = entityResolver.getObjEntity(FlattenedTest3.class).getRelationship(
+                FlattenedTest3.TO_FT1_PROPERTY);
+
+        FlattenedArcKey update = new FlattenedArcKey(src, target, r1);
+        FlattenedArcKey update1 = new FlattenedArcKey(target, src, r1.getReverseRelationship());
+
+        ObjRelationship r3 = entityResolver.getObjEntity(FlattenedTest1.class).getRelationship(
+                FlattenedTest1.FT3OVER_COMPLEX_PROPERTY);
+
+        FlattenedArcKey update2 = new FlattenedArcKey(target, src, r3);
+
+        assertTrue(update.equals(update1));
+        assertFalse(update.equals(update2));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedArcKeyTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedArcKeyTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedArcKeyTest.java
deleted file mode 100644
index a0c5714..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedArcKeyTest.java
+++ /dev/null
@@ -1,89 +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.ObjectId;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.map.ObjRelationship;
-import org.apache.cayenne.testdo.relationship.FlattenedTest1;
-import org.apache.cayenne.testdo.relationship.FlattenedTest3;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.RELATIONSHIPS_PROJECT)
-public class FlattenedArcKeyTest extends ServerCase {
-
-    @Inject
-    private EntityResolver entityResolver;
-
-    public void testAttributes() {
-        ObjectId src = new ObjectId("X");
-        ObjectId target = new ObjectId("Y");
-        ObjRelationship r1 = entityResolver.getObjEntity(FlattenedTest3.class).getRelationship(
-                FlattenedTest3.TO_FT1_PROPERTY);
-
-        FlattenedArcKey update = new FlattenedArcKey(src, target, r1);
-
-        assertSame(src, update.id1.getSourceId());
-        assertSame(target, update.id2.getSourceId());
-        assertSame(r1, update.relationship);
-    }
-
-    public void testHashCode() {
-        ObjectId src = new ObjectId("X");
-        ObjectId target = new ObjectId("Y");
-        ObjRelationship r1 = entityResolver.getObjEntity(FlattenedTest3.class).getRelationship(
-                FlattenedTest3.TO_FT1_PROPERTY);
-
-        FlattenedArcKey update = new FlattenedArcKey(src, target, r1);
-        FlattenedArcKey update1 = new FlattenedArcKey(target, src, r1.getReverseRelationship());
-
-        ObjRelationship r3 = entityResolver.getObjEntity(FlattenedTest1.class).getRelationship(
-                FlattenedTest1.FT3OVER_COMPLEX_PROPERTY);
-
-        FlattenedArcKey update2 = new FlattenedArcKey(target, src, r3);
-
-        int h = update.hashCode();
-        int h1 = update1.hashCode();
-        int h2 = update2.hashCode();
-        assertTrue(h == h1);
-        assertTrue(h == update.hashCode());
-        assertFalse(h == h2);
-    }
-
-    public void testEquals() {
-        ObjectId src = new ObjectId("X");
-        ObjectId target = new ObjectId("Y");
-        ObjRelationship r1 = entityResolver.getObjEntity(FlattenedTest3.class).getRelationship(
-                FlattenedTest3.TO_FT1_PROPERTY);
-
-        FlattenedArcKey update = new FlattenedArcKey(src, target, r1);
-        FlattenedArcKey update1 = new FlattenedArcKey(target, src, r1.getReverseRelationship());
-
-        ObjRelationship r3 = entityResolver.getObjEntity(FlattenedTest1.class).getRelationship(
-                FlattenedTest1.FT3OVER_COMPLEX_PROPERTY);
-
-        FlattenedArcKey update2 = new FlattenedArcKey(target, src, r3);
-
-        assertTrue(update.equals(update1));
-        assertFalse(update.equals(update2));
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedPrefetchIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedPrefetchIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedPrefetchIT.java
new file mode 100644
index 0000000..92cea2f
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedPrefetchIT.java
@@ -0,0 +1,267 @@
+/*****************************************************************
+ *   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.PersistenceState;
+import org.apache.cayenne.ValueHolder;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.PrefetchTreeNode;
+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.ArtGroup;
+import org.apache.cayenne.testdo.testmap.Artist;
+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.Types;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class FlattenedPrefetchIT extends ServerCase {
+
+    @Inject
+    protected DataChannelInterceptor queryInterceptor;
+
+    @Inject
+    protected ObjectContext context;
+
+    @Inject
+    protected DBHelper dbHelper;
+
+    protected TableHelper tArtist;
+    protected TableHelper tPainting;
+    protected TableHelper tArtgroup;
+    protected TableHelper tArtistGroup;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("PAINTING_INFO");
+        dbHelper.deleteAll("PAINTING");
+        dbHelper.deleteAll("PAINTING1");
+        dbHelper.deleteAll("ARTIST_EXHIBIT");
+        dbHelper.deleteAll("ARTIST_GROUP");
+        dbHelper.deleteAll("ARTIST");
+        dbHelper.update("ARTGROUP").set("PARENT_GROUP_ID", null, Types.INTEGER).execute();
+        dbHelper.deleteAll("ARTGROUP");
+
+        tArtist = new TableHelper(dbHelper, "ARTIST");
+        tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
+
+        tPainting = new TableHelper(dbHelper, "PAINTING");
+        tPainting.setColumns(
+                "PAINTING_ID",
+                "PAINTING_TITLE",
+                "ARTIST_ID",
+                "ESTIMATED_PRICE");
+
+        tArtgroup = new TableHelper(dbHelper, "ARTGROUP");
+        tArtgroup.setColumns("GROUP_ID", "NAME");
+
+        tArtistGroup = new TableHelper(dbHelper, "ARTIST_GROUP");
+        tArtistGroup.setColumns("ARTIST_ID", "GROUP_ID");
+    }
+
+    protected void createPrefetchDataSet1() throws Exception {
+        tArtist.insert(33001, "artist1");
+        tArtist.insert(33002, "artist2");
+        tArtist.insert(33003, "artist3");
+
+        tArtgroup.insert(33001, "group1");
+        tArtgroup.insert(33002, "group2");
+
+        tArtistGroup.insert(33001, 33001);
+        tArtistGroup.insert(33001, 33002);
+        tArtistGroup.insert(33002, 33002);
+        tArtistGroup.insert(33003, 33002);
+    }
+
+    protected void createPrefetchDataSet2() throws Exception {
+        tArtist.insert(33001, "artist1");
+        tArtist.insert(33002, "artist2");
+        tArtist.insert(33003, "artist3");
+        
+        tArtgroup.insert(33001, "group1");
+        tArtgroup.insert(33002, "group2");
+      
+        tArtistGroup.insert(33001, 33001);
+        tArtistGroup.insert(33001, 33002);
+        tArtistGroup.insert(33002, 33002);
+        tArtistGroup.insert(33003, 33002);
+        tPainting.insert(33001, "P_artist11", 33001, 1000);
+        tPainting.insert(33002, "P_artist12", 33001, 2000);
+        tPainting.insert(33003, "P_artist21", 33002, 3000);
+    }
+
+    public void testManyToMany() throws Exception {
+        createPrefetchDataSet1();
+
+        SelectQuery q = new SelectQuery(Artist.class);
+        q.addPrefetch(Artist.GROUP_ARRAY_PROPERTY);
+
+        final List<Artist> objects = context.performQuery(q);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                assertEquals(3, objects.size());
+
+                for (Artist a : objects) {
+                    List<ArtGroup> list = a.getGroupArray();
+
+                    assertNotNull(list);
+                    assertFalse(
+                            "artist's groups not resolved: " + a,
+                            ((ValueHolder) list).isFault());
+                    assertTrue(list.size() > 0);
+
+                    for (ArtGroup g : list) {
+                        assertEquals(PersistenceState.COMMITTED, g.getPersistenceState());
+                    }
+
+                    // assert no duplicates
+                    Set<ArtGroup> s = new HashSet<ArtGroup>(list);
+                    assertEquals(s.size(), list.size());
+                }
+            }
+        });
+    }
+
+    public void testMultiPrefetch() throws Exception {
+        createPrefetchDataSet2();
+
+        SelectQuery q = new SelectQuery(Painting.class);
+        q.addPrefetch(Painting.TO_ARTIST_PROPERTY);
+        q.addPrefetch(Painting.TO_ARTIST_PROPERTY + '.' + Artist.GROUP_ARRAY_PROPERTY);
+
+        final List<Painting> objects = context.performQuery(q);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                assertEquals(3, objects.size());
+
+                for (Painting p : objects) {
+                    Artist a = p.getToArtist();
+                    assertEquals(PersistenceState.COMMITTED, a.getPersistenceState());
+
+                    List<ArtGroup> list = a.getGroupArray();
+                    assertNotNull(list);
+                    assertFalse(
+                            "artist's groups not resolved: " + a,
+                            ((ValueHolder) list).isFault());
+                    assertTrue(list.size() > 0);
+
+                    for (ArtGroup g : list) {
+                        assertEquals(PersistenceState.COMMITTED, g.getPersistenceState());
+                    }
+
+                    // assert no duplicates
+                    Set<ArtGroup> s = new HashSet<ArtGroup>(list);
+                    assertEquals(s.size(), list.size());
+                }
+            }
+        });
+    }
+
+    public void testJointManyToMany() throws Exception {
+        createPrefetchDataSet1();
+
+        SelectQuery q = new SelectQuery(Artist.class);
+        q.addPrefetch(Artist.GROUP_ARRAY_PROPERTY).setSemantics(
+                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+
+        final List<Artist> objects = context.performQuery(q);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                assertEquals(3, objects.size());
+
+                for (Artist a : objects) {
+                    List<ArtGroup> list = a.getGroupArray();
+
+                    assertNotNull(list);
+                    assertFalse(
+                            "artist's groups not resolved: " + a,
+                            ((ValueHolder) list).isFault());
+                    assertTrue(list.size() > 0);
+
+                    for (ArtGroup g : list) {
+                        assertEquals(PersistenceState.COMMITTED, g.getPersistenceState());
+                    }
+
+                    // assert no duplicates
+                    Set<ArtGroup> s = new HashSet<ArtGroup>(list);
+                    assertEquals(s.size(), list.size());
+                }
+            }
+        });
+
+    }
+
+    public void testJointMultiPrefetch() throws Exception {
+        createPrefetchDataSet2();
+
+        SelectQuery q = new SelectQuery(Painting.class);
+        q.addPrefetch(Painting.TO_ARTIST_PROPERTY).setSemantics(
+                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+        q
+                .addPrefetch(
+                        Painting.TO_ARTIST_PROPERTY + '.' + Artist.GROUP_ARRAY_PROPERTY)
+                .setSemantics(PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+
+        final List<Painting> objects = context.performQuery(q);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                assertEquals(3, objects.size());
+
+                for (Painting p : objects) {
+                    Artist a = p.getToArtist();
+                    assertEquals(PersistenceState.COMMITTED, a.getPersistenceState());
+
+                    List<ArtGroup> list = a.getGroupArray();
+                    assertNotNull(list);
+                    assertFalse(
+                            "artist's groups not resolved: " + a,
+                            ((ValueHolder) list).isFault());
+                    assertTrue(list.size() > 0);
+
+                    for (ArtGroup g : list) {
+                        assertEquals(PersistenceState.COMMITTED, g.getPersistenceState());
+                    }
+
+                    // assert no duplicates
+
+                    Set<ArtGroup> s = new HashSet<ArtGroup>(list);
+                    assertEquals(s.size(), list.size());
+                }
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedPrefetchTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedPrefetchTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedPrefetchTest.java
deleted file mode 100644
index 2bbba64..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedPrefetchTest.java
+++ /dev/null
@@ -1,267 +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.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.sql.Types;
-
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.PersistenceState;
-import org.apache.cayenne.ValueHolder;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.PrefetchTreeNode;
-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.ArtGroup;
-import org.apache.cayenne.testdo.testmap.Artist;
-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;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class FlattenedPrefetchTest extends ServerCase {
-
-    @Inject
-    protected DataChannelInterceptor queryInterceptor;
-
-    @Inject
-    protected ObjectContext context;
-
-    @Inject
-    protected DBHelper dbHelper;
-
-    protected TableHelper tArtist;
-    protected TableHelper tPainting;
-    protected TableHelper tArtgroup;
-    protected TableHelper tArtistGroup;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("PAINTING_INFO");
-        dbHelper.deleteAll("PAINTING");
-        dbHelper.deleteAll("PAINTING1");
-        dbHelper.deleteAll("ARTIST_EXHIBIT");
-        dbHelper.deleteAll("ARTIST_GROUP");
-        dbHelper.deleteAll("ARTIST");
-        dbHelper.update("ARTGROUP").set("PARENT_GROUP_ID", null, Types.INTEGER).execute();
-        dbHelper.deleteAll("ARTGROUP");
-
-        tArtist = new TableHelper(dbHelper, "ARTIST");
-        tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
-
-        tPainting = new TableHelper(dbHelper, "PAINTING");
-        tPainting.setColumns(
-                "PAINTING_ID",
-                "PAINTING_TITLE",
-                "ARTIST_ID",
-                "ESTIMATED_PRICE");
-
-        tArtgroup = new TableHelper(dbHelper, "ARTGROUP");
-        tArtgroup.setColumns("GROUP_ID", "NAME");
-
-        tArtistGroup = new TableHelper(dbHelper, "ARTIST_GROUP");
-        tArtistGroup.setColumns("ARTIST_ID", "GROUP_ID");
-    }
-
-    protected void createPrefetchDataSet1() throws Exception {
-        tArtist.insert(33001, "artist1");
-        tArtist.insert(33002, "artist2");
-        tArtist.insert(33003, "artist3");
-
-        tArtgroup.insert(33001, "group1");
-        tArtgroup.insert(33002, "group2");
-
-        tArtistGroup.insert(33001, 33001);
-        tArtistGroup.insert(33001, 33002);
-        tArtistGroup.insert(33002, 33002);
-        tArtistGroup.insert(33003, 33002);
-    }
-
-    protected void createPrefetchDataSet2() throws Exception {
-        tArtist.insert(33001, "artist1");
-        tArtist.insert(33002, "artist2");
-        tArtist.insert(33003, "artist3");
-        
-        tArtgroup.insert(33001, "group1");
-        tArtgroup.insert(33002, "group2");
-      
-        tArtistGroup.insert(33001, 33001);
-        tArtistGroup.insert(33001, 33002);
-        tArtistGroup.insert(33002, 33002);
-        tArtistGroup.insert(33003, 33002);
-        tPainting.insert(33001, "P_artist11", 33001, 1000);
-        tPainting.insert(33002, "P_artist12", 33001, 2000);
-        tPainting.insert(33003, "P_artist21", 33002, 3000);
-    }
-
-    public void testManyToMany() throws Exception {
-        createPrefetchDataSet1();
-
-        SelectQuery q = new SelectQuery(Artist.class);
-        q.addPrefetch(Artist.GROUP_ARRAY_PROPERTY);
-
-        final List<Artist> objects = context.performQuery(q);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                assertEquals(3, objects.size());
-
-                for (Artist a : objects) {
-                    List<ArtGroup> list = a.getGroupArray();
-
-                    assertNotNull(list);
-                    assertFalse(
-                            "artist's groups not resolved: " + a,
-                            ((ValueHolder) list).isFault());
-                    assertTrue(list.size() > 0);
-
-                    for (ArtGroup g : list) {
-                        assertEquals(PersistenceState.COMMITTED, g.getPersistenceState());
-                    }
-
-                    // assert no duplicates
-                    Set<ArtGroup> s = new HashSet<ArtGroup>(list);
-                    assertEquals(s.size(), list.size());
-                }
-            }
-        });
-    }
-
-    public void testMultiPrefetch() throws Exception {
-        createPrefetchDataSet2();
-
-        SelectQuery q = new SelectQuery(Painting.class);
-        q.addPrefetch(Painting.TO_ARTIST_PROPERTY);
-        q.addPrefetch(Painting.TO_ARTIST_PROPERTY + '.' + Artist.GROUP_ARRAY_PROPERTY);
-
-        final List<Painting> objects = context.performQuery(q);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                assertEquals(3, objects.size());
-
-                for (Painting p : objects) {
-                    Artist a = p.getToArtist();
-                    assertEquals(PersistenceState.COMMITTED, a.getPersistenceState());
-
-                    List<ArtGroup> list = a.getGroupArray();
-                    assertNotNull(list);
-                    assertFalse(
-                            "artist's groups not resolved: " + a,
-                            ((ValueHolder) list).isFault());
-                    assertTrue(list.size() > 0);
-
-                    for (ArtGroup g : list) {
-                        assertEquals(PersistenceState.COMMITTED, g.getPersistenceState());
-                    }
-
-                    // assert no duplicates
-                    Set<ArtGroup> s = new HashSet<ArtGroup>(list);
-                    assertEquals(s.size(), list.size());
-                }
-            }
-        });
-    }
-
-    public void testJointManyToMany() throws Exception {
-        createPrefetchDataSet1();
-
-        SelectQuery q = new SelectQuery(Artist.class);
-        q.addPrefetch(Artist.GROUP_ARRAY_PROPERTY).setSemantics(
-                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
-
-        final List<Artist> objects = context.performQuery(q);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                assertEquals(3, objects.size());
-
-                for (Artist a : objects) {
-                    List<ArtGroup> list = a.getGroupArray();
-
-                    assertNotNull(list);
-                    assertFalse(
-                            "artist's groups not resolved: " + a,
-                            ((ValueHolder) list).isFault());
-                    assertTrue(list.size() > 0);
-
-                    for (ArtGroup g : list) {
-                        assertEquals(PersistenceState.COMMITTED, g.getPersistenceState());
-                    }
-
-                    // assert no duplicates
-                    Set<ArtGroup> s = new HashSet<ArtGroup>(list);
-                    assertEquals(s.size(), list.size());
-                }
-            }
-        });
-
-    }
-
-    public void testJointMultiPrefetch() throws Exception {
-        createPrefetchDataSet2();
-
-        SelectQuery q = new SelectQuery(Painting.class);
-        q.addPrefetch(Painting.TO_ARTIST_PROPERTY).setSemantics(
-                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
-        q
-                .addPrefetch(
-                        Painting.TO_ARTIST_PROPERTY + '.' + Artist.GROUP_ARRAY_PROPERTY)
-                .setSemantics(PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
-
-        final List<Painting> objects = context.performQuery(q);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                assertEquals(3, objects.size());
-
-                for (Painting p : objects) {
-                    Artist a = p.getToArtist();
-                    assertEquals(PersistenceState.COMMITTED, a.getPersistenceState());
-
-                    List<ArtGroup> list = a.getGroupArray();
-                    assertNotNull(list);
-                    assertFalse(
-                            "artist's groups not resolved: " + a,
-                            ((ValueHolder) list).isFault());
-                    assertTrue(list.size() > 0);
-
-                    for (ArtGroup g : list) {
-                        assertEquals(PersistenceState.COMMITTED, g.getPersistenceState());
-                    }
-
-                    // assert no duplicates
-
-                    Set<ArtGroup> s = new HashSet<ArtGroup>(list);
-                    assertEquals(s.size(), list.size());
-                }
-            }
-        });
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedRelationshipInContextIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedRelationshipInContextIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedRelationshipInContextIT.java
new file mode 100644
index 0000000..b3fbc2e
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedRelationshipInContextIT.java
@@ -0,0 +1,100 @@
+/*****************************************************************
+ *   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.Fault;
+import org.apache.cayenne.PersistenceState;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.reflect.ArcProperty;
+import org.apache.cayenne.reflect.ClassDescriptor;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.relationship.FlattenedTest3;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.util.List;
+
+@UseServerRuntime(ServerCase.RELATIONSHIPS_PROJECT)
+public class FlattenedRelationshipInContextIT extends ServerCase {
+
+    @Inject
+    protected DataContext context;
+
+    @Inject
+    protected DBHelper dbHelper;
+
+    private TableHelper tFlattenedTest1;
+    private TableHelper tFlattenedTest2;
+    private TableHelper tFlattenedTest3;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("COMPLEX_JOIN");
+        dbHelper.deleteAll("FLATTENED_TEST_4");
+        dbHelper.deleteAll("FLATTENED_TEST_3");
+        dbHelper.deleteAll("FLATTENED_TEST_2");
+        dbHelper.deleteAll("FLATTENED_TEST_1");
+
+        tFlattenedTest1 = new TableHelper(dbHelper, "FLATTENED_TEST_1");
+        tFlattenedTest1.setColumns("FT1_ID", "NAME");
+
+        tFlattenedTest2 = new TableHelper(dbHelper, "FLATTENED_TEST_2");
+        tFlattenedTest2.setColumns("FT2_ID", "FT1_ID", "NAME");
+
+        tFlattenedTest3 = new TableHelper(dbHelper, "FLATTENED_TEST_3");
+        tFlattenedTest3.setColumns("FT3_ID", "FT2_ID", "NAME");
+    }
+
+    protected void createFlattenedTestDataSet() throws Exception {
+        tFlattenedTest1.insert(1, "ft1");
+        tFlattenedTest1.insert(2, "ft12");
+        tFlattenedTest2.insert(1, 1, "ft2");
+        tFlattenedTest3.insert(1, 1, "ft3");
+    }
+
+    public void testIsToOneTargetModifiedFlattenedFault1() throws Exception {
+
+        createFlattenedTestDataSet();
+
+        // fetch
+        List<?> ft3s = context.performQuery(new SelectQuery(FlattenedTest3.class));
+        assertEquals(1, ft3s.size());
+        FlattenedTest3 ft3 = (FlattenedTest3) ft3s.get(0);
+
+        // mark as dirty for the purpose of the test...
+        ft3.setPersistenceState(PersistenceState.MODIFIED);
+
+        assertTrue(ft3.readPropertyDirectly("toFT1") instanceof Fault);
+
+        // test that checking for modifications does not trigger a fault, and generally
+        // works well
+
+        ClassDescriptor d = context.getEntityResolver().getClassDescriptor(
+                "FlattenedTest3");
+        ArcProperty flattenedRel = (ArcProperty) d.getProperty("toFT1");
+
+        ObjectDiff diff = context.getObjectStore().registerDiff(ft3.getObjectId(), null);
+        assertFalse(DataRowUtils.isToOneTargetModified(flattenedRel, ft3, diff));
+        assertTrue(ft3.readPropertyDirectly("toFT1") instanceof Fault);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedRelationshipInContextTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedRelationshipInContextTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedRelationshipInContextTest.java
deleted file mode 100644
index afe7030..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/FlattenedRelationshipInContextTest.java
+++ /dev/null
@@ -1,100 +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.Fault;
-import org.apache.cayenne.PersistenceState;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.reflect.ArcProperty;
-import org.apache.cayenne.reflect.ClassDescriptor;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.test.jdbc.TableHelper;
-import org.apache.cayenne.testdo.relationship.FlattenedTest3;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.RELATIONSHIPS_PROJECT)
-public class FlattenedRelationshipInContextTest extends ServerCase {
-
-    @Inject
-    protected DataContext context;
-
-    @Inject
-    protected DBHelper dbHelper;
-
-    private TableHelper tFlattenedTest1;
-    private TableHelper tFlattenedTest2;
-    private TableHelper tFlattenedTest3;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("COMPLEX_JOIN");
-        dbHelper.deleteAll("FLATTENED_TEST_4");
-        dbHelper.deleteAll("FLATTENED_TEST_3");
-        dbHelper.deleteAll("FLATTENED_TEST_2");
-        dbHelper.deleteAll("FLATTENED_TEST_1");
-
-        tFlattenedTest1 = new TableHelper(dbHelper, "FLATTENED_TEST_1");
-        tFlattenedTest1.setColumns("FT1_ID", "NAME");
-
-        tFlattenedTest2 = new TableHelper(dbHelper, "FLATTENED_TEST_2");
-        tFlattenedTest2.setColumns("FT2_ID", "FT1_ID", "NAME");
-
-        tFlattenedTest3 = new TableHelper(dbHelper, "FLATTENED_TEST_3");
-        tFlattenedTest3.setColumns("FT3_ID", "FT2_ID", "NAME");
-    }
-
-    protected void createFlattenedTestDataSet() throws Exception {
-        tFlattenedTest1.insert(1, "ft1");
-        tFlattenedTest1.insert(2, "ft12");
-        tFlattenedTest2.insert(1, 1, "ft2");
-        tFlattenedTest3.insert(1, 1, "ft3");
-    }
-
-    public void testIsToOneTargetModifiedFlattenedFault1() throws Exception {
-
-        createFlattenedTestDataSet();
-
-        // fetch
-        List<?> ft3s = context.performQuery(new SelectQuery(FlattenedTest3.class));
-        assertEquals(1, ft3s.size());
-        FlattenedTest3 ft3 = (FlattenedTest3) ft3s.get(0);
-
-        // mark as dirty for the purpose of the test...
-        ft3.setPersistenceState(PersistenceState.MODIFIED);
-
-        assertTrue(ft3.readPropertyDirectly("toFT1") instanceof Fault);
-
-        // test that checking for modifications does not trigger a fault, and generally
-        // works well
-
-        ClassDescriptor d = context.getEntityResolver().getClassDescriptor(
-                "FlattenedTest3");
-        ArcProperty flattenedRel = (ArcProperty) d.getProperty("toFT1");
-
-        ObjectDiff diff = context.getObjectStore().registerDiff(ft3.getObjectId(), null);
-        assertFalse(DataRowUtils.isToOneTargetModified(flattenedRel, ft3, diff));
-        assertTrue(ft3.readPropertyDirectly("toFT1") instanceof Fault);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/IdentityColumnsIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/IdentityColumnsIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/IdentityColumnsIT.java
new file mode 100644
index 0000000..b637efd
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/IdentityColumnsIT.java
@@ -0,0 +1,331 @@
+/*****************************************************************
+ *   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.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;
+
+import java.util.List;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class IdentityColumnsIT 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));
+    }
+}