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

[21/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/NestedDataContextWriteIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextWriteIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextWriteIT.java
new file mode 100644
index 0000000..569283c
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextWriteIT.java
@@ -0,0 +1,676 @@
+/*****************************************************************
+ *   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.PersistenceState;
+import org.apache.cayenne.Persistent;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.ObjRelationship;
+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.ArtGroup;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.testdo.testmap.Painting;
+import org.apache.cayenne.testdo.testmap.PaintingInfo;
+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.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+@UseServerRuntime("cayenne-small-testmap.xml")
+public class NestedDataContextWriteIT extends ServerCase {
+
+    @Inject
+    private ServerRuntime runtime;
+    
+    @Inject
+    private DataContext context;
+
+    @Inject
+    private DataChannelInterceptor queryInterceptor;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    private TableHelper tArtist;
+    private TableHelper tPainting;
+    private TableHelper tPaintingInfo;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("PAINTING_INFO");
+        dbHelper.deleteAll("PAINTING");
+        dbHelper.deleteAll("ARTIST_EXHIBIT");
+        dbHelper.deleteAll("ARTIST_GROUP");
+        dbHelper.deleteAll("ARTIST");
+
+        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").setColumnTypes(
+                Types.INTEGER,
+                Types.VARCHAR,
+                Types.BIGINT,
+                Types.DECIMAL);
+
+        tPaintingInfo = new TableHelper(dbHelper, "PAINTING_INFO");
+        tPaintingInfo.setColumns("PAINTING_ID", "TEXT_REVIEW", "IMAGE_BLOB");
+    }
+
+    private void createArtistsDataSet() throws Exception {
+        tArtist.insert(33001, "artist1");
+        tArtist.insert(33002, "artist2");
+        tArtist.insert(33003, "artist3");
+        tArtist.insert(33004, "artist4");
+    }
+
+    private void createMixedDataSet() throws Exception {
+        tArtist.insert(33001, "artist1");
+        tArtist.insert(33002, "artist2");
+        tArtist.insert(33003, "artist3");
+        tArtist.insert(33004, "artist4");
+        tPainting.insert(33001, "P_artist1", 33001, 3000);
+        tPainting.insert(33002, "P_artist2", 33002, 3000);
+        tPainting.insert(33003, "P_artist3", 33003, 3000);
+        tPainting.insert(33004, "P_artist4", 33004, 3000);
+        tPainting.insert(33005, "P_artist5", null, 3000);
+        tPainting.insert(33006, "P_artist6", 33001, 3000);
+    }
+
+    private void createNullifyToOneDataSet() throws Exception {
+        tArtist.insert(33001, "artist1");
+        tPainting.insert(33001, "P_artist1", 33001, 3000);
+    }
+
+    private void createSingleArtistDataSet() throws Exception {
+        tArtist.insert(33001, "artist1");
+    }
+
+    /**
+     * Ensures that created DataContext's ObjectStore retains unreferenced registered
+     * objects.
+     */
+    // TODO : pluggable retain strategy
+    private DataContext createDataContext() {
+        context.getObjectStore().objectMap = new HashMap<Object, Persistent>();
+        return context;
+    }
+
+    public void testDeleteNew() throws Exception {
+        createSingleArtistDataSet();
+
+        DataContext context = createDataContext();
+        ObjectContext childContext = runtime.newContext(context);
+
+        Artist a = Cayenne.objectForPK(childContext, Artist.class, 33001);
+        Painting p = childContext.newObject(Painting.class);
+        p.setPaintingTitle("X");
+        a.addToPaintingArray(p);
+
+        childContext.commitChangesToParent();
+
+        childContext.deleteObjects(p);
+        a.removeFromPaintingArray(p);
+
+        childContext.commitChangesToParent();
+    }
+
+    /**
+     * A test case for CAY-698 bug.
+     */
+    public void testNullifyToOne() throws Exception {
+        createNullifyToOneDataSet();
+
+        final DataContext context = createDataContext();
+        final ObjectContext childContext = runtime.newContext(context);
+        ObjectContext childContextPeer = runtime.newContext(context);
+
+        final Painting childP1 = Cayenne.objectForPK(childContext, Painting.class, 33001);
+
+        // trigger object creation in the peer nested DC
+        Cayenne.objectForPK(childContextPeer, Painting.class, 33001);
+        childP1.setToArtist(null);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                childContext.commitChangesToParent();
+                assertEquals(PersistenceState.COMMITTED, childP1.getPersistenceState());
+
+                Painting parentP1 = (Painting) context.getGraphManager().getNode(
+                        childP1.getObjectId());
+
+                assertNotNull(parentP1);
+                assertEquals(PersistenceState.MODIFIED, parentP1.getPersistenceState());
+                assertNull(parentP1.getToArtist());
+            }
+        });
+    }
+
+    public void testCommitChangesToParent() throws Exception {
+        createArtistsDataSet();
+
+        final DataContext context = createDataContext();
+        final ObjectContext childContext = runtime.newContext(context);
+
+        // make sure we fetch in predictable order
+        SelectQuery query = new SelectQuery(Artist.class);
+        query.addOrdering(Artist.ARTIST_NAME_PROPERTY, SortOrder.ASCENDING);
+        List<?> objects = childContext.performQuery(query);
+
+        assertEquals(4, objects.size());
+
+        final Artist childNew = childContext.newObject(Artist.class);
+        childNew.setArtistName("NNN");
+
+        final Artist childModified = (Artist) objects.get(0);
+        childModified.setArtistName("MMM");
+
+        final Artist childCommitted = (Artist) objects.get(1);
+
+        final Artist childHollow = (Artist) objects.get(3);
+        childContext.invalidateObjects(childHollow);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                childContext.commitChangesToParent();
+
+                // * all modified child objects must be in committed state now
+                // * all modifications should be propagated to the parent
+                // * no actual commit should occur.
+
+                assertEquals(PersistenceState.COMMITTED, childNew.getPersistenceState());
+                assertEquals(PersistenceState.COMMITTED, childModified
+                        .getPersistenceState());
+                assertEquals(PersistenceState.COMMITTED, childCommitted
+                        .getPersistenceState());
+                assertEquals(PersistenceState.HOLLOW, childHollow.getPersistenceState());
+
+                Artist parentNew = (Artist) context.getGraphManager().getNode(
+                        childNew.getObjectId());
+                Artist parentModified = (Artist) context.getGraphManager().getNode(
+                        childModified.getObjectId());
+                Artist parentCommitted = (Artist) context.getGraphManager().getNode(
+                        childCommitted.getObjectId());
+                Artist parentHollow = (Artist) context.getGraphManager().getNode(
+                        childHollow.getObjectId());
+
+                assertNotNull(parentNew);
+                assertEquals(PersistenceState.NEW, parentNew.getPersistenceState());
+                assertEquals("NNN", parentNew.getArtistName());
+
+                assertNotNull(parentModified);
+                assertEquals(PersistenceState.MODIFIED, parentModified
+                        .getPersistenceState());
+                assertEquals("MMM", parentModified.getArtistName());
+                assertNotNull(context.getObjectStore().getChangesByObjectId().get(
+                        parentModified.getObjectId()));
+
+                assertNotNull(parentCommitted);
+                assertEquals(PersistenceState.COMMITTED, parentCommitted
+                        .getPersistenceState());
+
+                assertNotNull(parentHollow);
+                // TODO: we can assert that when we figure out how nested "invalidate"
+                // should
+                // work
+                // assertEquals(PersistenceState.HOLLOW,
+                // parentHollow.getPersistenceState());
+            }
+        });
+    }
+
+    public void testCommitChangesToParentDeleted() throws Exception {
+        createArtistsDataSet();
+
+        DataContext context = createDataContext();
+        ObjectContext childContext = runtime.newContext(context);
+
+        // make sure we fetch in predictable order
+        SelectQuery query = new SelectQuery(Artist.class);
+        query.addOrdering(Artist.ARTIST_NAME_PROPERTY, SortOrder.ASCENDING);
+        List<?> objects = childContext.performQuery(query);
+
+        assertEquals(4, objects.size());
+
+        // delete AND modify
+        Artist childDeleted = (Artist) objects.get(2);
+        childContext.deleteObjects(childDeleted);
+        childDeleted.setArtistName("DDD");
+
+        // don't block queries - on delete Cayenne may need to resolve delete rules via
+        // fetch
+        childContext.commitChangesToParent();
+
+        // * all modified child objects must be in committed state now
+        // * all modifications should be propagated to the parent
+        // * no actual commit should occur.
+
+        assertEquals(PersistenceState.TRANSIENT, childDeleted.getPersistenceState());
+
+        Artist parentDeleted = (Artist) context.getGraphManager().getNode(
+                childDeleted.getObjectId());
+
+        assertNotNull(parentDeleted);
+        assertEquals(PersistenceState.DELETED, parentDeleted.getPersistenceState());
+        assertEquals("DDD", parentDeleted.getArtistName());
+    }
+
+    public void testCommitChanges() throws Exception {
+        createArtistsDataSet();
+
+        DataContext context = createDataContext();
+        ObjectContext childContext = runtime.newContext(context);
+
+        // make sure we fetch in predictable order
+        SelectQuery query = new SelectQuery(Artist.class);
+        query.addOrdering(Artist.ARTIST_NAME_PROPERTY, SortOrder.ASCENDING);
+        List<?> objects = childContext.performQuery(query);
+
+        assertEquals(4, objects.size());
+
+        Artist childNew = childContext.newObject(Artist.class);
+        childNew.setArtistName("NNN");
+
+        Artist childModified = (Artist) objects.get(0);
+        childModified.setArtistName("MMM");
+
+        Artist childCommitted = (Artist) objects.get(1);
+
+        // delete AND modify
+        Artist childDeleted = (Artist) objects.get(2);
+        childContext.deleteObjects(childDeleted);
+        childDeleted.setArtistName("DDD");
+
+        Artist childHollow = (Artist) objects.get(3);
+        childContext.invalidateObjects(childHollow);
+
+        childContext.commitChanges();
+
+        assertEquals(PersistenceState.COMMITTED, childNew.getPersistenceState());
+        assertEquals(PersistenceState.COMMITTED, childModified.getPersistenceState());
+        assertEquals(PersistenceState.COMMITTED, childCommitted.getPersistenceState());
+        assertEquals(PersistenceState.TRANSIENT, childDeleted.getPersistenceState());
+        assertEquals(PersistenceState.HOLLOW, childHollow.getPersistenceState());
+
+        Artist parentNew = (Artist) context.getGraphManager().getNode(
+                childNew.getObjectId());
+        Artist parentModified = (Artist) context.getGraphManager().getNode(
+                childModified.getObjectId());
+        Artist parentCommitted = (Artist) context.getGraphManager().getNode(
+                childCommitted.getObjectId());
+        Artist parentDeleted = (Artist) context.getGraphManager().getNode(
+                childDeleted.getObjectId());
+        Artist parentHollow = (Artist) context.getGraphManager().getNode(
+                childHollow.getObjectId());
+
+        assertNotNull(parentNew);
+        assertEquals(PersistenceState.COMMITTED, parentNew.getPersistenceState());
+        assertEquals("NNN", parentNew.getArtistName());
+
+        assertNotNull(parentModified);
+        assertEquals(PersistenceState.COMMITTED, parentModified.getPersistenceState());
+        assertEquals("MMM", parentModified.getArtistName());
+        assertNull(context.getObjectStore().getChangesByObjectId().get(
+                parentModified.getObjectId()));
+
+        assertNull("Deleted object should not be registered.", parentDeleted);
+
+        assertNotNull(parentCommitted);
+        assertEquals(PersistenceState.COMMITTED, parentCommitted.getPersistenceState());
+
+        assertNotNull(parentHollow);
+    }
+
+    public void testCommitChangesToParent_MergeProperties() throws Exception {
+        createMixedDataSet();
+
+        final DataContext context = createDataContext();
+        final ObjectContext childContext = runtime.newContext(context);
+
+        // make sure we fetch in predictable order
+        SelectQuery query = new SelectQuery(Painting.class);
+        query.addOrdering(Painting.PAINTING_TITLE_PROPERTY, SortOrder.ASCENDING);
+        List<?> objects = childContext.performQuery(query);
+
+        assertEquals(6, objects.size());
+
+        final Painting childModifiedSimple = (Painting) objects.get(0);
+        childModifiedSimple.setPaintingTitle("C_PT");
+
+        final Painting childModifiedToOne = (Painting) objects.get(1);
+        childModifiedToOne.setToArtist(childModifiedSimple.getToArtist());
+
+        final Artist childModifiedToMany = ((Painting) objects.get(2)).getToArtist();
+
+        // ensure painting array is fully resolved...
+        childModifiedToMany.getPaintingArray().size();
+        childModifiedToMany.addToPaintingArray((Painting) objects.get(3));
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                Painting parentModifiedSimple = null;
+                Artist parentModifiedToMany = null;
+
+                childContext.commitChangesToParent();
+
+                assertEquals(PersistenceState.COMMITTED, childModifiedSimple
+                        .getPersistenceState());
+                assertEquals(PersistenceState.COMMITTED, childModifiedToOne
+                        .getPersistenceState());
+                assertEquals(PersistenceState.COMMITTED, childModifiedToMany
+                        .getPersistenceState());
+
+                parentModifiedSimple = (Painting) context.getGraphManager().getNode(
+                        childModifiedSimple.getObjectId());
+
+                Painting parentModifiedToOne = (Painting) context
+                        .getGraphManager()
+                        .getNode(childModifiedToOne.getObjectId());
+
+                parentModifiedToMany = (Artist) context.getGraphManager().getNode(
+                        childModifiedToMany.getObjectId());
+
+                assertNotNull(parentModifiedSimple);
+                assertEquals(PersistenceState.MODIFIED, parentModifiedSimple
+                        .getPersistenceState());
+                assertEquals("C_PT", parentModifiedSimple.getPaintingTitle());
+                assertNotNull(context.getObjectStore().getChangesByObjectId().get(
+                        parentModifiedSimple.getObjectId()));
+
+                assertNotNull(parentModifiedToOne);
+                assertEquals(PersistenceState.MODIFIED, parentModifiedToOne
+                        .getPersistenceState());
+                assertNotNull(parentModifiedToOne.getToArtist());
+                assertEquals(33001, Cayenne.intPKForObject(parentModifiedToOne
+                        .getToArtist()));
+                assertNotNull(context.getObjectStore().getChangesByObjectId().get(
+                        parentModifiedToOne.getObjectId()));
+
+                // indirectly modified....
+                assertNotNull(parentModifiedToMany);
+                assertEquals(PersistenceState.MODIFIED, parentModifiedToMany
+                        .getPersistenceState());
+
+                // here query is expected, as the parent was hollow and its to-many
+                // relationship
+                // is unresolved
+                List<?> paintings = parentModifiedToMany.getPaintingArray();
+                assertEquals(2, paintings.size());
+            }
+        });
+    }
+
+    public void testCommitChangesToParentPropagatedKey() throws Exception {
+        final DataContext context = createDataContext();
+        final ObjectContext childContext = runtime.newContext(context);
+
+        final Painting childMaster = childContext.newObject(Painting.class);
+        childMaster.setPaintingTitle("Master");
+
+        final PaintingInfo childDetail1 = childContext.newObject(PaintingInfo.class);
+        childDetail1.setTextReview("Detail1");
+        childDetail1.setPainting(childMaster);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                childContext.commitChangesToParent();
+
+                assertEquals(PersistenceState.COMMITTED, childMaster
+                        .getPersistenceState());
+                assertEquals(PersistenceState.COMMITTED, childDetail1
+                        .getPersistenceState());
+
+                Painting parentMaster = (Painting) context.getGraphManager().getNode(
+                        childMaster.getObjectId());
+
+                assertNotNull(parentMaster);
+                assertEquals(PersistenceState.NEW, parentMaster.getPersistenceState());
+
+                PaintingInfo parentDetail1 = (PaintingInfo) context
+                        .getGraphManager()
+                        .getNode(childDetail1.getObjectId());
+
+                assertNotNull(parentDetail1);
+                assertEquals(PersistenceState.NEW, parentDetail1.getPersistenceState());
+
+                assertSame(parentMaster, parentDetail1.getPainting());
+                assertSame(parentDetail1, parentMaster.getToPaintingInfo());
+            }
+        });
+    }
+
+    public void testCommitChangesToParentFlattened() throws Exception {
+
+        final DataContext context = createDataContext();
+        final ObjectContext childContext = runtime.newContext(context);
+
+        final Artist childO1 = childContext.newObject(Artist.class);
+        childO1.setArtistName("Master");
+
+        final ArtGroup childO2 = childContext.newObject(ArtGroup.class);
+        childO2.setName("Detail1");
+        childO2.addToArtistArray(childO1);
+
+        ObjEntity ent = childContext.getEntityResolver().getObjEntity("ArtGroup");
+        Collection<ObjRelationship> rels = ent.getDeclaredRelationships();
+        for (ObjRelationship rel : rels) {
+            System.out.println(rel.getName());
+        }
+
+        assertEquals(1, childO1.getGroupArray().size());
+        assertEquals(1, childO2.getArtistArray().size());
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                childContext.commitChangesToParent();
+
+                assertEquals(PersistenceState.COMMITTED, childO1.getPersistenceState());
+                assertEquals(PersistenceState.COMMITTED, childO2.getPersistenceState());
+
+                Artist parentO1 = (Artist) context.getGraphManager().getNode(
+                        childO1.getObjectId());
+
+                assertNotNull(parentO1);
+                assertEquals(PersistenceState.NEW, parentO1.getPersistenceState());
+
+                ArtGroup parentO2 = (ArtGroup) context.getGraphManager().getNode(
+                        childO2.getObjectId());
+
+                assertNotNull(parentO2);
+                assertEquals(PersistenceState.NEW, parentO2.getPersistenceState());
+
+                assertEquals(1, parentO1.getGroupArray().size());
+                assertEquals(1, parentO2.getArtistArray().size());
+                assertTrue(parentO2.getArtistArray().contains(parentO1));
+                assertTrue(parentO1.getGroupArray().contains(parentO2));
+            }
+        });
+    }
+
+    public void testCommitChangesToParentFlattenedMultipleFlush() throws Exception {
+        final DataContext context = createDataContext();
+        final ObjectContext childContext = runtime.newContext(context);
+
+        final Artist childO1 = childContext.newObject(Artist.class);
+        childO1.setArtistName("o1");
+
+        final ArtGroup childO2 = childContext.newObject(ArtGroup.class);
+        childO2.setName("o2");
+        childO2.addToArtistArray(childO1);
+
+        childContext.commitChangesToParent();
+
+        final ArtGroup childO3 = childContext.newObject(ArtGroup.class);
+        childO3.setName("o3");
+        childO1.addToGroupArray(childO3);
+
+        assertEquals(2, childO1.getGroupArray().size());
+        assertEquals(1, childO2.getArtistArray().size());
+        assertEquals(1, childO3.getArtistArray().size());
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                childContext.commitChangesToParent();
+
+                assertEquals(PersistenceState.COMMITTED, childO1.getPersistenceState());
+                assertEquals(PersistenceState.COMMITTED, childO2.getPersistenceState());
+                assertEquals(PersistenceState.COMMITTED, childO3.getPersistenceState());
+
+                Artist parentO1 = (Artist) context.getGraphManager().getNode(
+                        childO1.getObjectId());
+
+                assertNotNull(parentO1);
+                assertEquals(PersistenceState.NEW, parentO1.getPersistenceState());
+
+                ArtGroup parentO2 = (ArtGroup) context.getGraphManager().getNode(
+                        childO2.getObjectId());
+
+                assertNotNull(parentO2);
+                assertEquals(PersistenceState.NEW, parentO2.getPersistenceState());
+
+                ArtGroup parentO3 = (ArtGroup) context.getGraphManager().getNode(
+                        childO3.getObjectId());
+
+                assertNotNull(parentO3);
+                assertEquals(PersistenceState.NEW, parentO3.getPersistenceState());
+
+                assertEquals(2, parentO1.getGroupArray().size());
+                assertEquals(1, parentO2.getArtistArray().size());
+                assertEquals(1, parentO3.getArtistArray().size());
+                assertTrue(parentO2.getArtistArray().contains(parentO1));
+                assertTrue(parentO3.getArtistArray().contains(parentO1));
+                assertTrue(parentO1.getGroupArray().contains(parentO2));
+                assertTrue(parentO1.getGroupArray().contains(parentO3));
+            }
+        });
+
+        childO1.removeFromGroupArray(childO2);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                childContext.commitChangesToParent();
+
+                assertEquals(PersistenceState.COMMITTED, childO1.getPersistenceState());
+                assertEquals(PersistenceState.COMMITTED, childO2.getPersistenceState());
+                assertEquals(PersistenceState.COMMITTED, childO3.getPersistenceState());
+
+                Artist parentO1 = (Artist) context.getGraphManager().getNode(
+                        childO1.getObjectId());
+
+                assertNotNull(parentO1);
+                assertEquals(PersistenceState.NEW, parentO1.getPersistenceState());
+
+                ArtGroup parentO2 = (ArtGroup) context.getGraphManager().getNode(
+                        childO2.getObjectId());
+
+                assertNotNull(parentO2);
+                assertEquals(PersistenceState.NEW, parentO2.getPersistenceState());
+
+                ArtGroup parentO3 = (ArtGroup) context.getGraphManager().getNode(
+                        childO3.getObjectId());
+
+                assertNotNull(parentO3);
+                assertEquals(PersistenceState.NEW, parentO3.getPersistenceState());
+
+                assertEquals(1, parentO1.getGroupArray().size());
+                assertEquals(0, parentO2.getArtistArray().size());
+                assertEquals(1, parentO3.getArtistArray().size());
+
+                assertTrue(parentO3.getArtistArray().contains(parentO1));
+                assertTrue(parentO1.getGroupArray().contains(parentO3));
+            }
+        });
+    }
+
+    public void testAddRemove() {
+
+        DataContext context = createDataContext();
+        ObjectContext child = runtime.newContext(context);
+
+        Artist a = child.newObject(Artist.class);
+        a.setArtistName("X");
+        child.commitChanges();
+
+        Painting p1 = child.newObject(Painting.class);
+        p1.setPaintingTitle("P1");
+        a.addToPaintingArray(p1);
+
+        Painting p2 = child.newObject(Painting.class);
+        p2.setPaintingTitle("P2");
+        a.addToPaintingArray(p2);
+
+        a.removeFromPaintingArray(p2);
+
+        // this causes an error on commit
+        child.deleteObjects(p2);
+
+        child.commitChangesToParent();
+
+    }
+
+    public void testCAY1194() throws Exception {
+        DataContext context = createDataContext();
+
+        Artist artist = context.newObject(Artist.class);
+        artist.setArtistName("111");
+        ObjectContext child = runtime.newContext(context);
+
+        Painting painting = child.newObject(Painting.class);
+        painting.setPaintingTitle("222");
+
+        Artist localParentMt = child.localObject(artist);
+        assertEquals(0, artist.getPaintingArray().size());
+        assertEquals(0, localParentMt.getPaintingArray().size());
+
+        painting.setToArtist(localParentMt);
+
+        assertEquals(0, artist.getPaintingArray().size());
+        assertEquals(1, localParentMt.getPaintingArray().size());
+        assertEquals(localParentMt.getPaintingArray().get(0).getObjectContext(), child);
+
+        child.commitChangesToParent();
+        assertEquals(1, artist.getPaintingArray().size());
+        assertEquals(artist.getPaintingArray().get(0).getObjectContext(), context);
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextWriteTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextWriteTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextWriteTest.java
deleted file mode 100644
index d0f6802..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContextWriteTest.java
+++ /dev/null
@@ -1,676 +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.Types;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-
-import org.apache.cayenne.Cayenne;
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.PersistenceState;
-import org.apache.cayenne.Persistent;
-import org.apache.cayenne.configuration.server.ServerRuntime;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.map.ObjRelationship;
-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.ArtGroup;
-import org.apache.cayenne.testdo.testmap.Artist;
-import org.apache.cayenne.testdo.testmap.Painting;
-import org.apache.cayenne.testdo.testmap.PaintingInfo;
-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("cayenne-small-testmap.xml")
-public class NestedDataContextWriteTest extends ServerCase {
-
-    @Inject
-    private ServerRuntime runtime;
-    
-    @Inject
-    private DataContext context;
-
-    @Inject
-    private DataChannelInterceptor queryInterceptor;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    private TableHelper tArtist;
-    private TableHelper tPainting;
-    private TableHelper tPaintingInfo;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("PAINTING_INFO");
-        dbHelper.deleteAll("PAINTING");
-        dbHelper.deleteAll("ARTIST_EXHIBIT");
-        dbHelper.deleteAll("ARTIST_GROUP");
-        dbHelper.deleteAll("ARTIST");
-
-        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").setColumnTypes(
-                Types.INTEGER,
-                Types.VARCHAR,
-                Types.BIGINT,
-                Types.DECIMAL);
-
-        tPaintingInfo = new TableHelper(dbHelper, "PAINTING_INFO");
-        tPaintingInfo.setColumns("PAINTING_ID", "TEXT_REVIEW", "IMAGE_BLOB");
-    }
-
-    private void createArtistsDataSet() throws Exception {
-        tArtist.insert(33001, "artist1");
-        tArtist.insert(33002, "artist2");
-        tArtist.insert(33003, "artist3");
-        tArtist.insert(33004, "artist4");
-    }
-
-    private void createMixedDataSet() throws Exception {
-        tArtist.insert(33001, "artist1");
-        tArtist.insert(33002, "artist2");
-        tArtist.insert(33003, "artist3");
-        tArtist.insert(33004, "artist4");
-        tPainting.insert(33001, "P_artist1", 33001, 3000);
-        tPainting.insert(33002, "P_artist2", 33002, 3000);
-        tPainting.insert(33003, "P_artist3", 33003, 3000);
-        tPainting.insert(33004, "P_artist4", 33004, 3000);
-        tPainting.insert(33005, "P_artist5", null, 3000);
-        tPainting.insert(33006, "P_artist6", 33001, 3000);
-    }
-
-    private void createNullifyToOneDataSet() throws Exception {
-        tArtist.insert(33001, "artist1");
-        tPainting.insert(33001, "P_artist1", 33001, 3000);
-    }
-
-    private void createSingleArtistDataSet() throws Exception {
-        tArtist.insert(33001, "artist1");
-    }
-
-    /**
-     * Ensures that created DataContext's ObjectStore retains unreferenced registered
-     * objects.
-     */
-    // TODO : pluggable retain strategy
-    private DataContext createDataContext() {
-        context.getObjectStore().objectMap = new HashMap<Object, Persistent>();
-        return context;
-    }
-
-    public void testDeleteNew() throws Exception {
-        createSingleArtistDataSet();
-
-        DataContext context = createDataContext();
-        ObjectContext childContext = runtime.newContext(context);
-
-        Artist a = Cayenne.objectForPK(childContext, Artist.class, 33001);
-        Painting p = childContext.newObject(Painting.class);
-        p.setPaintingTitle("X");
-        a.addToPaintingArray(p);
-
-        childContext.commitChangesToParent();
-
-        childContext.deleteObjects(p);
-        a.removeFromPaintingArray(p);
-
-        childContext.commitChangesToParent();
-    }
-
-    /**
-     * A test case for CAY-698 bug.
-     */
-    public void testNullifyToOne() throws Exception {
-        createNullifyToOneDataSet();
-
-        final DataContext context = createDataContext();
-        final ObjectContext childContext = runtime.newContext(context);
-        ObjectContext childContextPeer = runtime.newContext(context);
-
-        final Painting childP1 = Cayenne.objectForPK(childContext, Painting.class, 33001);
-
-        // trigger object creation in the peer nested DC
-        Cayenne.objectForPK(childContextPeer, Painting.class, 33001);
-        childP1.setToArtist(null);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                childContext.commitChangesToParent();
-                assertEquals(PersistenceState.COMMITTED, childP1.getPersistenceState());
-
-                Painting parentP1 = (Painting) context.getGraphManager().getNode(
-                        childP1.getObjectId());
-
-                assertNotNull(parentP1);
-                assertEquals(PersistenceState.MODIFIED, parentP1.getPersistenceState());
-                assertNull(parentP1.getToArtist());
-            }
-        });
-    }
-
-    public void testCommitChangesToParent() throws Exception {
-        createArtistsDataSet();
-
-        final DataContext context = createDataContext();
-        final ObjectContext childContext = runtime.newContext(context);
-
-        // make sure we fetch in predictable order
-        SelectQuery query = new SelectQuery(Artist.class);
-        query.addOrdering(Artist.ARTIST_NAME_PROPERTY, SortOrder.ASCENDING);
-        List<?> objects = childContext.performQuery(query);
-
-        assertEquals(4, objects.size());
-
-        final Artist childNew = childContext.newObject(Artist.class);
-        childNew.setArtistName("NNN");
-
-        final Artist childModified = (Artist) objects.get(0);
-        childModified.setArtistName("MMM");
-
-        final Artist childCommitted = (Artist) objects.get(1);
-
-        final Artist childHollow = (Artist) objects.get(3);
-        childContext.invalidateObjects(childHollow);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                childContext.commitChangesToParent();
-
-                // * all modified child objects must be in committed state now
-                // * all modifications should be propagated to the parent
-                // * no actual commit should occur.
-
-                assertEquals(PersistenceState.COMMITTED, childNew.getPersistenceState());
-                assertEquals(PersistenceState.COMMITTED, childModified
-                        .getPersistenceState());
-                assertEquals(PersistenceState.COMMITTED, childCommitted
-                        .getPersistenceState());
-                assertEquals(PersistenceState.HOLLOW, childHollow.getPersistenceState());
-
-                Artist parentNew = (Artist) context.getGraphManager().getNode(
-                        childNew.getObjectId());
-                Artist parentModified = (Artist) context.getGraphManager().getNode(
-                        childModified.getObjectId());
-                Artist parentCommitted = (Artist) context.getGraphManager().getNode(
-                        childCommitted.getObjectId());
-                Artist parentHollow = (Artist) context.getGraphManager().getNode(
-                        childHollow.getObjectId());
-
-                assertNotNull(parentNew);
-                assertEquals(PersistenceState.NEW, parentNew.getPersistenceState());
-                assertEquals("NNN", parentNew.getArtistName());
-
-                assertNotNull(parentModified);
-                assertEquals(PersistenceState.MODIFIED, parentModified
-                        .getPersistenceState());
-                assertEquals("MMM", parentModified.getArtistName());
-                assertNotNull(context.getObjectStore().getChangesByObjectId().get(
-                        parentModified.getObjectId()));
-
-                assertNotNull(parentCommitted);
-                assertEquals(PersistenceState.COMMITTED, parentCommitted
-                        .getPersistenceState());
-
-                assertNotNull(parentHollow);
-                // TODO: we can assert that when we figure out how nested "invalidate"
-                // should
-                // work
-                // assertEquals(PersistenceState.HOLLOW,
-                // parentHollow.getPersistenceState());
-            }
-        });
-    }
-
-    public void testCommitChangesToParentDeleted() throws Exception {
-        createArtistsDataSet();
-
-        DataContext context = createDataContext();
-        ObjectContext childContext = runtime.newContext(context);
-
-        // make sure we fetch in predictable order
-        SelectQuery query = new SelectQuery(Artist.class);
-        query.addOrdering(Artist.ARTIST_NAME_PROPERTY, SortOrder.ASCENDING);
-        List<?> objects = childContext.performQuery(query);
-
-        assertEquals(4, objects.size());
-
-        // delete AND modify
-        Artist childDeleted = (Artist) objects.get(2);
-        childContext.deleteObjects(childDeleted);
-        childDeleted.setArtistName("DDD");
-
-        // don't block queries - on delete Cayenne may need to resolve delete rules via
-        // fetch
-        childContext.commitChangesToParent();
-
-        // * all modified child objects must be in committed state now
-        // * all modifications should be propagated to the parent
-        // * no actual commit should occur.
-
-        assertEquals(PersistenceState.TRANSIENT, childDeleted.getPersistenceState());
-
-        Artist parentDeleted = (Artist) context.getGraphManager().getNode(
-                childDeleted.getObjectId());
-
-        assertNotNull(parentDeleted);
-        assertEquals(PersistenceState.DELETED, parentDeleted.getPersistenceState());
-        assertEquals("DDD", parentDeleted.getArtistName());
-    }
-
-    public void testCommitChanges() throws Exception {
-        createArtistsDataSet();
-
-        DataContext context = createDataContext();
-        ObjectContext childContext = runtime.newContext(context);
-
-        // make sure we fetch in predictable order
-        SelectQuery query = new SelectQuery(Artist.class);
-        query.addOrdering(Artist.ARTIST_NAME_PROPERTY, SortOrder.ASCENDING);
-        List<?> objects = childContext.performQuery(query);
-
-        assertEquals(4, objects.size());
-
-        Artist childNew = childContext.newObject(Artist.class);
-        childNew.setArtistName("NNN");
-
-        Artist childModified = (Artist) objects.get(0);
-        childModified.setArtistName("MMM");
-
-        Artist childCommitted = (Artist) objects.get(1);
-
-        // delete AND modify
-        Artist childDeleted = (Artist) objects.get(2);
-        childContext.deleteObjects(childDeleted);
-        childDeleted.setArtistName("DDD");
-
-        Artist childHollow = (Artist) objects.get(3);
-        childContext.invalidateObjects(childHollow);
-
-        childContext.commitChanges();
-
-        assertEquals(PersistenceState.COMMITTED, childNew.getPersistenceState());
-        assertEquals(PersistenceState.COMMITTED, childModified.getPersistenceState());
-        assertEquals(PersistenceState.COMMITTED, childCommitted.getPersistenceState());
-        assertEquals(PersistenceState.TRANSIENT, childDeleted.getPersistenceState());
-        assertEquals(PersistenceState.HOLLOW, childHollow.getPersistenceState());
-
-        Artist parentNew = (Artist) context.getGraphManager().getNode(
-                childNew.getObjectId());
-        Artist parentModified = (Artist) context.getGraphManager().getNode(
-                childModified.getObjectId());
-        Artist parentCommitted = (Artist) context.getGraphManager().getNode(
-                childCommitted.getObjectId());
-        Artist parentDeleted = (Artist) context.getGraphManager().getNode(
-                childDeleted.getObjectId());
-        Artist parentHollow = (Artist) context.getGraphManager().getNode(
-                childHollow.getObjectId());
-
-        assertNotNull(parentNew);
-        assertEquals(PersistenceState.COMMITTED, parentNew.getPersistenceState());
-        assertEquals("NNN", parentNew.getArtistName());
-
-        assertNotNull(parentModified);
-        assertEquals(PersistenceState.COMMITTED, parentModified.getPersistenceState());
-        assertEquals("MMM", parentModified.getArtistName());
-        assertNull(context.getObjectStore().getChangesByObjectId().get(
-                parentModified.getObjectId()));
-
-        assertNull("Deleted object should not be registered.", parentDeleted);
-
-        assertNotNull(parentCommitted);
-        assertEquals(PersistenceState.COMMITTED, parentCommitted.getPersistenceState());
-
-        assertNotNull(parentHollow);
-    }
-
-    public void testCommitChangesToParent_MergeProperties() throws Exception {
-        createMixedDataSet();
-
-        final DataContext context = createDataContext();
-        final ObjectContext childContext = runtime.newContext(context);
-
-        // make sure we fetch in predictable order
-        SelectQuery query = new SelectQuery(Painting.class);
-        query.addOrdering(Painting.PAINTING_TITLE_PROPERTY, SortOrder.ASCENDING);
-        List<?> objects = childContext.performQuery(query);
-
-        assertEquals(6, objects.size());
-
-        final Painting childModifiedSimple = (Painting) objects.get(0);
-        childModifiedSimple.setPaintingTitle("C_PT");
-
-        final Painting childModifiedToOne = (Painting) objects.get(1);
-        childModifiedToOne.setToArtist(childModifiedSimple.getToArtist());
-
-        final Artist childModifiedToMany = ((Painting) objects.get(2)).getToArtist();
-
-        // ensure painting array is fully resolved...
-        childModifiedToMany.getPaintingArray().size();
-        childModifiedToMany.addToPaintingArray((Painting) objects.get(3));
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                Painting parentModifiedSimple = null;
-                Artist parentModifiedToMany = null;
-
-                childContext.commitChangesToParent();
-
-                assertEquals(PersistenceState.COMMITTED, childModifiedSimple
-                        .getPersistenceState());
-                assertEquals(PersistenceState.COMMITTED, childModifiedToOne
-                        .getPersistenceState());
-                assertEquals(PersistenceState.COMMITTED, childModifiedToMany
-                        .getPersistenceState());
-
-                parentModifiedSimple = (Painting) context.getGraphManager().getNode(
-                        childModifiedSimple.getObjectId());
-
-                Painting parentModifiedToOne = (Painting) context
-                        .getGraphManager()
-                        .getNode(childModifiedToOne.getObjectId());
-
-                parentModifiedToMany = (Artist) context.getGraphManager().getNode(
-                        childModifiedToMany.getObjectId());
-
-                assertNotNull(parentModifiedSimple);
-                assertEquals(PersistenceState.MODIFIED, parentModifiedSimple
-                        .getPersistenceState());
-                assertEquals("C_PT", parentModifiedSimple.getPaintingTitle());
-                assertNotNull(context.getObjectStore().getChangesByObjectId().get(
-                        parentModifiedSimple.getObjectId()));
-
-                assertNotNull(parentModifiedToOne);
-                assertEquals(PersistenceState.MODIFIED, parentModifiedToOne
-                        .getPersistenceState());
-                assertNotNull(parentModifiedToOne.getToArtist());
-                assertEquals(33001, Cayenne.intPKForObject(parentModifiedToOne
-                        .getToArtist()));
-                assertNotNull(context.getObjectStore().getChangesByObjectId().get(
-                        parentModifiedToOne.getObjectId()));
-
-                // indirectly modified....
-                assertNotNull(parentModifiedToMany);
-                assertEquals(PersistenceState.MODIFIED, parentModifiedToMany
-                        .getPersistenceState());
-
-                // here query is expected, as the parent was hollow and its to-many
-                // relationship
-                // is unresolved
-                List<?> paintings = parentModifiedToMany.getPaintingArray();
-                assertEquals(2, paintings.size());
-            }
-        });
-    }
-
-    public void testCommitChangesToParentPropagatedKey() throws Exception {
-        final DataContext context = createDataContext();
-        final ObjectContext childContext = runtime.newContext(context);
-
-        final Painting childMaster = childContext.newObject(Painting.class);
-        childMaster.setPaintingTitle("Master");
-
-        final PaintingInfo childDetail1 = childContext.newObject(PaintingInfo.class);
-        childDetail1.setTextReview("Detail1");
-        childDetail1.setPainting(childMaster);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                childContext.commitChangesToParent();
-
-                assertEquals(PersistenceState.COMMITTED, childMaster
-                        .getPersistenceState());
-                assertEquals(PersistenceState.COMMITTED, childDetail1
-                        .getPersistenceState());
-
-                Painting parentMaster = (Painting) context.getGraphManager().getNode(
-                        childMaster.getObjectId());
-
-                assertNotNull(parentMaster);
-                assertEquals(PersistenceState.NEW, parentMaster.getPersistenceState());
-
-                PaintingInfo parentDetail1 = (PaintingInfo) context
-                        .getGraphManager()
-                        .getNode(childDetail1.getObjectId());
-
-                assertNotNull(parentDetail1);
-                assertEquals(PersistenceState.NEW, parentDetail1.getPersistenceState());
-
-                assertSame(parentMaster, parentDetail1.getPainting());
-                assertSame(parentDetail1, parentMaster.getToPaintingInfo());
-            }
-        });
-    }
-
-    public void testCommitChangesToParentFlattened() throws Exception {
-
-        final DataContext context = createDataContext();
-        final ObjectContext childContext = runtime.newContext(context);
-
-        final Artist childO1 = childContext.newObject(Artist.class);
-        childO1.setArtistName("Master");
-
-        final ArtGroup childO2 = childContext.newObject(ArtGroup.class);
-        childO2.setName("Detail1");
-        childO2.addToArtistArray(childO1);
-
-        ObjEntity ent = childContext.getEntityResolver().getObjEntity("ArtGroup");
-        Collection<ObjRelationship> rels = ent.getDeclaredRelationships();
-        for (ObjRelationship rel : rels) {
-            System.out.println(rel.getName());
-        }
-
-        assertEquals(1, childO1.getGroupArray().size());
-        assertEquals(1, childO2.getArtistArray().size());
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                childContext.commitChangesToParent();
-
-                assertEquals(PersistenceState.COMMITTED, childO1.getPersistenceState());
-                assertEquals(PersistenceState.COMMITTED, childO2.getPersistenceState());
-
-                Artist parentO1 = (Artist) context.getGraphManager().getNode(
-                        childO1.getObjectId());
-
-                assertNotNull(parentO1);
-                assertEquals(PersistenceState.NEW, parentO1.getPersistenceState());
-
-                ArtGroup parentO2 = (ArtGroup) context.getGraphManager().getNode(
-                        childO2.getObjectId());
-
-                assertNotNull(parentO2);
-                assertEquals(PersistenceState.NEW, parentO2.getPersistenceState());
-
-                assertEquals(1, parentO1.getGroupArray().size());
-                assertEquals(1, parentO2.getArtistArray().size());
-                assertTrue(parentO2.getArtistArray().contains(parentO1));
-                assertTrue(parentO1.getGroupArray().contains(parentO2));
-            }
-        });
-    }
-
-    public void testCommitChangesToParentFlattenedMultipleFlush() throws Exception {
-        final DataContext context = createDataContext();
-        final ObjectContext childContext = runtime.newContext(context);
-
-        final Artist childO1 = childContext.newObject(Artist.class);
-        childO1.setArtistName("o1");
-
-        final ArtGroup childO2 = childContext.newObject(ArtGroup.class);
-        childO2.setName("o2");
-        childO2.addToArtistArray(childO1);
-
-        childContext.commitChangesToParent();
-
-        final ArtGroup childO3 = childContext.newObject(ArtGroup.class);
-        childO3.setName("o3");
-        childO1.addToGroupArray(childO3);
-
-        assertEquals(2, childO1.getGroupArray().size());
-        assertEquals(1, childO2.getArtistArray().size());
-        assertEquals(1, childO3.getArtistArray().size());
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                childContext.commitChangesToParent();
-
-                assertEquals(PersistenceState.COMMITTED, childO1.getPersistenceState());
-                assertEquals(PersistenceState.COMMITTED, childO2.getPersistenceState());
-                assertEquals(PersistenceState.COMMITTED, childO3.getPersistenceState());
-
-                Artist parentO1 = (Artist) context.getGraphManager().getNode(
-                        childO1.getObjectId());
-
-                assertNotNull(parentO1);
-                assertEquals(PersistenceState.NEW, parentO1.getPersistenceState());
-
-                ArtGroup parentO2 = (ArtGroup) context.getGraphManager().getNode(
-                        childO2.getObjectId());
-
-                assertNotNull(parentO2);
-                assertEquals(PersistenceState.NEW, parentO2.getPersistenceState());
-
-                ArtGroup parentO3 = (ArtGroup) context.getGraphManager().getNode(
-                        childO3.getObjectId());
-
-                assertNotNull(parentO3);
-                assertEquals(PersistenceState.NEW, parentO3.getPersistenceState());
-
-                assertEquals(2, parentO1.getGroupArray().size());
-                assertEquals(1, parentO2.getArtistArray().size());
-                assertEquals(1, parentO3.getArtistArray().size());
-                assertTrue(parentO2.getArtistArray().contains(parentO1));
-                assertTrue(parentO3.getArtistArray().contains(parentO1));
-                assertTrue(parentO1.getGroupArray().contains(parentO2));
-                assertTrue(parentO1.getGroupArray().contains(parentO3));
-            }
-        });
-
-        childO1.removeFromGroupArray(childO2);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                childContext.commitChangesToParent();
-
-                assertEquals(PersistenceState.COMMITTED, childO1.getPersistenceState());
-                assertEquals(PersistenceState.COMMITTED, childO2.getPersistenceState());
-                assertEquals(PersistenceState.COMMITTED, childO3.getPersistenceState());
-
-                Artist parentO1 = (Artist) context.getGraphManager().getNode(
-                        childO1.getObjectId());
-
-                assertNotNull(parentO1);
-                assertEquals(PersistenceState.NEW, parentO1.getPersistenceState());
-
-                ArtGroup parentO2 = (ArtGroup) context.getGraphManager().getNode(
-                        childO2.getObjectId());
-
-                assertNotNull(parentO2);
-                assertEquals(PersistenceState.NEW, parentO2.getPersistenceState());
-
-                ArtGroup parentO3 = (ArtGroup) context.getGraphManager().getNode(
-                        childO3.getObjectId());
-
-                assertNotNull(parentO3);
-                assertEquals(PersistenceState.NEW, parentO3.getPersistenceState());
-
-                assertEquals(1, parentO1.getGroupArray().size());
-                assertEquals(0, parentO2.getArtistArray().size());
-                assertEquals(1, parentO3.getArtistArray().size());
-
-                assertTrue(parentO3.getArtistArray().contains(parentO1));
-                assertTrue(parentO1.getGroupArray().contains(parentO3));
-            }
-        });
-    }
-
-    public void testAddRemove() {
-
-        DataContext context = createDataContext();
-        ObjectContext child = runtime.newContext(context);
-
-        Artist a = child.newObject(Artist.class);
-        a.setArtistName("X");
-        child.commitChanges();
-
-        Painting p1 = child.newObject(Painting.class);
-        p1.setPaintingTitle("P1");
-        a.addToPaintingArray(p1);
-
-        Painting p2 = child.newObject(Painting.class);
-        p2.setPaintingTitle("P2");
-        a.addToPaintingArray(p2);
-
-        a.removeFromPaintingArray(p2);
-
-        // this causes an error on commit
-        child.deleteObjects(p2);
-
-        child.commitChangesToParent();
-
-    }
-
-    public void testCAY1194() throws Exception {
-        DataContext context = createDataContext();
-
-        Artist artist = context.newObject(Artist.class);
-        artist.setArtistName("111");
-        ObjectContext child = runtime.newContext(context);
-
-        Painting painting = child.newObject(Painting.class);
-        painting.setPaintingTitle("222");
-
-        Artist localParentMt = child.localObject(artist);
-        assertEquals(0, artist.getPaintingArray().size());
-        assertEquals(0, localParentMt.getPaintingArray().size());
-
-        painting.setToArtist(localParentMt);
-
-        assertEquals(0, artist.getPaintingArray().size());
-        assertEquals(1, localParentMt.getPaintingArray().size());
-        assertEquals(localParentMt.getPaintingArray().get(0).getObjectContext(), child);
-
-        child.commitChangesToParent();
-        assertEquals(1, artist.getPaintingArray().size());
-        assertEquals(artist.getPaintingArray().get(0).getObjectContext(), context);
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContext_DeadlockIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContext_DeadlockIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContext_DeadlockIT.java
new file mode 100644
index 0000000..a46c506
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContext_DeadlockIT.java
@@ -0,0 +1,128 @@
+/*****************************************************************
+ *   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 java.util.Random;
+
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+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 NestedDataContext_DeadlockIT extends ServerCase {
+
+    @Inject
+    private DataContext parent;
+
+    @Inject
+    private ServerRuntime runtime;
+
+    @Inject
+    protected DBHelper dbHelper;
+
+    protected TableHelper tArtist;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("PAINTING_INFO");
+        dbHelper.deleteAll("PAINTING");
+        dbHelper.deleteAll("ARTIST_EXHIBIT");
+        dbHelper.deleteAll("ARTIST_GROUP");
+        dbHelper.deleteAll("ARTIST");
+
+        tArtist = new TableHelper(dbHelper, "ARTIST");
+        tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
+    }
+
+    private void createArtists() throws Exception {
+        for (int i = 0; i < 300; i++) {
+            tArtist.insert(i + 1, "X" + i);
+        }
+    }
+
+    public void testDeadlock() throws Exception {
+
+        createArtists();
+
+        final Thread[] threads = new Thread[2];
+
+        Random rnd = new Random(System.currentTimeMillis());
+        for (int i = 0; i < threads.length; i++) {
+            threads[i] = new UpdateThread("UpdateThread-" + i,
+                    runtime.newContext(parent), rnd);
+        }
+
+        for (int i = 0; i < threads.length; i++) {
+            threads[i].start();
+        }
+
+        new ParallelTestContainer() {
+
+            @Override
+            protected void assertResult() throws Exception {
+                for (int i = 0; i < threads.length; i++) {
+                    // unfortunately here we'll have to leave some dead threads
+                    // behind... Of course if there's no deadlock, there won't
+                    // be a leak either
+                    assertFalse("Deadlocked thread", threads[i].isAlive());
+                }
+            }
+        }.runTest(20000);
+
+    }
+
+    static class UpdateThread extends Thread {
+
+        protected ObjectContext nestedContext;
+        protected Random rnd;
+
+        UpdateThread(String name, ObjectContext nestedContext, Random rnd) {
+            super(name);
+            setDaemon(true);
+            this.nestedContext = nestedContext;
+            this.rnd = rnd;
+        }
+
+        @Override
+        public void run() {
+
+            List<Artist> artists = nestedContext.performQuery(new SelectQuery(
+                    Artist.class));
+
+            for (int i = 0; i < 100; i++) {
+
+                for (int j = 0; j < 5; j++) {
+                    int index = rnd.nextInt(artists.size());
+                    Artist a = artists.get(index);
+                    a.setArtistName("Y" + rnd.nextInt());
+                }
+
+                nestedContext.commitChanges();
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContext_DeadlockTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContext_DeadlockTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContext_DeadlockTest.java
deleted file mode 100644
index 2761073..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/NestedDataContext_DeadlockTest.java
+++ /dev/null
@@ -1,128 +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 java.util.Random;
-
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.configuration.server.ServerRuntime;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.test.jdbc.TableHelper;
-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 NestedDataContext_DeadlockTest extends ServerCase {
-
-    @Inject
-    private DataContext parent;
-
-    @Inject
-    private ServerRuntime runtime;
-
-    @Inject
-    protected DBHelper dbHelper;
-
-    protected TableHelper tArtist;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("PAINTING_INFO");
-        dbHelper.deleteAll("PAINTING");
-        dbHelper.deleteAll("ARTIST_EXHIBIT");
-        dbHelper.deleteAll("ARTIST_GROUP");
-        dbHelper.deleteAll("ARTIST");
-
-        tArtist = new TableHelper(dbHelper, "ARTIST");
-        tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
-    }
-
-    private void createArtists() throws Exception {
-        for (int i = 0; i < 300; i++) {
-            tArtist.insert(i + 1, "X" + i);
-        }
-    }
-
-    public void testDeadlock() throws Exception {
-
-        createArtists();
-
-        final Thread[] threads = new Thread[2];
-
-        Random rnd = new Random(System.currentTimeMillis());
-        for (int i = 0; i < threads.length; i++) {
-            threads[i] = new UpdateThread("UpdateThread-" + i,
-                    runtime.newContext(parent), rnd);
-        }
-
-        for (int i = 0; i < threads.length; i++) {
-            threads[i].start();
-        }
-
-        new ParallelTestContainer() {
-
-            @Override
-            protected void assertResult() throws Exception {
-                for (int i = 0; i < threads.length; i++) {
-                    // unfortunately here we'll have to leave some dead threads
-                    // behind... Of course if there's no deadlock, there won't
-                    // be a leak either
-                    assertFalse("Deadlocked thread", threads[i].isAlive());
-                }
-            }
-        }.runTest(20000);
-
-    }
-
-    static class UpdateThread extends Thread {
-
-        protected ObjectContext nestedContext;
-        protected Random rnd;
-
-        UpdateThread(String name, ObjectContext nestedContext, Random rnd) {
-            super(name);
-            setDaemon(true);
-            this.nestedContext = nestedContext;
-            this.rnd = rnd;
-        }
-
-        @Override
-        public void run() {
-
-            List<Artist> artists = nestedContext.performQuery(new SelectQuery(
-                    Artist.class));
-
-            for (int i = 0; i < 100; i++) {
-
-                for (int j = 0; j < 5; j++) {
-                    int index = rnd.nextInt(artists.size());
-                    Artist a = artists.get(index);
-                    a.setArtistName("Y" + rnd.nextInt());
-                }
-
-                nestedContext.commitChanges();
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/NumericTypesIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/NumericTypesIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/NumericTypesIT.java
new file mode 100644
index 0000000..4581852
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/NumericTypesIT.java
@@ -0,0 +1,295 @@
+/*****************************************************************
+ *   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.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.List;
+
+import org.apache.cayenne.ObjectId;
+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.query.SelectQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.testmap.BigDecimalEntity;
+import org.apache.cayenne.testdo.testmap.BigIntegerEntity;
+import org.apache.cayenne.testdo.testmap.BitTestEntity;
+import org.apache.cayenne.testdo.testmap.BooleanTestEntity;
+import org.apache.cayenne.testdo.testmap.DecimalPKTest1;
+import org.apache.cayenne.testdo.testmap.DecimalPKTestEntity;
+import org.apache.cayenne.testdo.testmap.LongEntity;
+import org.apache.cayenne.testdo.testmap.SmallintTestEntity;
+import org.apache.cayenne.testdo.testmap.TinyintTestEntity;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+/**
+ */
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class NumericTypesIT extends ServerCase {
+
+    @Inject
+    protected DataContext context;
+
+    @Inject
+    protected DataContext context1;
+
+    @Inject
+    protected ServerRuntime runtime;
+
+    @Inject
+    protected DBHelper dbHelper;
+
+    protected TableHelper tSmallintTest;
+    protected TableHelper tTinyintTest;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("BOOLEAN_TEST");
+        dbHelper.deleteAll("SMALLINT_TEST");
+        dbHelper.deleteAll("TINYINT_TEST");
+        dbHelper.deleteAll("DECIMAL_PK_TST");
+
+        tSmallintTest = new TableHelper(dbHelper, "SMALLINT_TEST");
+        tSmallintTest.setColumns("ID", "SMALLINT_COL");
+
+        tTinyintTest = new TableHelper(dbHelper, "TINYINT_TEST");
+        tTinyintTest.setColumns("ID", "TINYINT_COL");
+    }
+
+    protected void createShortDataSet() throws Exception {
+        tSmallintTest.insert(1, 9999);
+        tSmallintTest.insert(2, 3333);
+    }
+
+    protected void createTinyintDataSet() throws Exception {
+        tTinyintTest.insert(1, 81);
+        tTinyintTest.insert(2, 50);
+    }
+
+    public void testLong() throws Exception {
+
+        LongEntity test = context.newObject(LongEntity.class);
+
+        Long i = new Long(Integer.MAX_VALUE + 10l);
+        test.setLongField(i);
+        context.commitChanges();
+
+        SelectQuery q = new SelectQuery(LongEntity.class);
+        LongEntity testRead = (LongEntity) context.performQuery(q).get(0);
+        assertNotNull(testRead.getLongField());
+        assertEquals(i, testRead.getLongField());
+
+        test.setLongField(null);
+        context.commitChanges();
+    }
+
+    public void testBigInteger() throws Exception {
+
+        BigIntegerEntity test = context.newObject(BigIntegerEntity.class);
+
+        BigInteger i = new BigInteger("1234567890");
+        test.setBigIntegerField(i);
+        context.commitChanges();
+
+        SelectQuery q = new SelectQuery(BigIntegerEntity.class);
+        BigIntegerEntity testRead = (BigIntegerEntity) context.performQuery(q).get(0);
+        assertNotNull(testRead.getBigIntegerField());
+        assertEquals(i, testRead.getBigIntegerField());
+
+        test.setBigIntegerField(null);
+        context.commitChanges();
+    }
+
+    public void testBigDecimal() throws Exception {
+
+        BigDecimalEntity test = context.newObject(BigDecimalEntity.class);
+
+        BigDecimal i = new BigDecimal("1234567890.44");
+        test.setBigDecimalField(i);
+        context.commitChanges();
+
+        SelectQuery q = new SelectQuery(BigDecimalEntity.class);
+        BigDecimalEntity testRead = (BigDecimalEntity) context.performQuery(q).get(0);
+        assertNotNull(testRead.getBigDecimalField());
+        assertEquals(i, testRead.getBigDecimalField());
+
+        test.setBigDecimalField(null);
+        context.commitChanges();
+    }
+
+    public void testShortInQualifier() throws Exception {
+        createShortDataSet();
+
+        // test
+        Expression qual = ExpressionFactory.matchExp("smallintCol", new Short("9999"));
+        List<?> objects = context.performQuery(new SelectQuery(
+                SmallintTestEntity.class,
+                qual));
+        assertEquals(1, objects.size());
+
+        SmallintTestEntity object = (SmallintTestEntity) objects.get(0);
+        assertEquals(new Short("9999"), object.getSmallintCol());
+    }
+
+    public void testShortInInsert() throws Exception {
+        SmallintTestEntity object = (SmallintTestEntity) (context)
+                .newObject("SmallintTestEntity");
+        object.setSmallintCol(new Short("1"));
+        context.commitChanges();
+    }
+
+    public void testTinyintInQualifier() throws Exception {
+        createTinyintDataSet();
+
+        // test
+        Expression qual = ExpressionFactory.matchExp("tinyintCol", new Byte((byte) 81));
+        List<?> objects = context.performQuery(new SelectQuery(
+                TinyintTestEntity.class,
+                qual));
+        assertEquals(1, objects.size());
+
+        TinyintTestEntity object = (TinyintTestEntity) objects.get(0);
+        assertEquals(new Byte((byte) 81), object.getTinyintCol());
+    }
+
+    public void testTinyintInInsert() throws Exception {
+        TinyintTestEntity object = (TinyintTestEntity) (context)
+                .newObject("TinyintTestEntity");
+        object.setTinyintCol(new Byte((byte) 1));
+        context.commitChanges();
+    }
+
+    public void testBooleanBit() throws Exception {
+
+        BitTestEntity trueObject = (BitTestEntity) context.newObject("BitTestEntity");
+        trueObject.setBitColumn(Boolean.TRUE);
+        BitTestEntity falseObject = (BitTestEntity) context.newObject("BitTestEntity");
+        falseObject.setBitColumn(Boolean.FALSE);
+        context.commitChanges();
+        context.invalidateObjects(trueObject, falseObject);
+
+        // fetch true...
+        Expression trueQ = ExpressionFactory.matchExp("bitColumn", Boolean.TRUE);
+        List<?> trueResult = context1.performQuery(new SelectQuery(
+                BitTestEntity.class,
+                trueQ));
+        assertEquals(1, trueResult.size());
+
+        BitTestEntity trueRefetched = (BitTestEntity) trueResult.get(0);
+        assertEquals(Boolean.TRUE, trueRefetched.getBitColumn());
+
+        // CAY-320. Simplifying the use of booleans to allow identity comparison.
+        assertNotSame(trueRefetched, trueObject);
+        assertSame(Boolean.TRUE, trueRefetched.getBitColumn());
+
+        // fetch false
+        Expression falseQ = ExpressionFactory.matchExp("bitColumn", Boolean.FALSE);
+        List<?> falseResult = context1.performQuery(new SelectQuery(
+                BitTestEntity.class,
+                falseQ));
+        assertEquals(1, falseResult.size());
+
+        BitTestEntity falseRefetched = (BitTestEntity) falseResult.get(0);
+        assertEquals(Boolean.FALSE, falseRefetched.getBitColumn());
+
+        // CAY-320. Simplifying the use of booleans to allow identity comparison.
+        assertNotSame(falseRefetched, falseObject);
+        assertSame(Boolean.FALSE, falseRefetched.getBitColumn());
+    }
+
+    public void testBooleanBoolean() throws Exception {
+
+        // populate (testing insert as well)
+        BooleanTestEntity trueObject = (BooleanTestEntity) context
+                .newObject("BooleanTestEntity");
+        trueObject.setBooleanColumn(Boolean.TRUE);
+        BooleanTestEntity falseObject = (BooleanTestEntity) context
+                .newObject("BooleanTestEntity");
+        falseObject.setBooleanColumn(Boolean.FALSE);
+        context.commitChanges();
+
+        context.invalidateObjects(trueObject, falseObject);
+
+        // fetch true...
+        Expression trueQ = ExpressionFactory.matchExp("booleanColumn", Boolean.TRUE);
+        List<?> trueResult = context1.performQuery(new SelectQuery(
+                BooleanTestEntity.class,
+                trueQ));
+        assertEquals(1, trueResult.size());
+
+        BooleanTestEntity trueRefetched = (BooleanTestEntity) trueResult.get(0);
+        assertEquals(Boolean.TRUE, trueRefetched.getBooleanColumn());
+
+        // CAY-320. Simplifying the use of booleans to allow identity comparison.
+        assertNotSame(trueRefetched, trueObject);
+        assertSame(Boolean.TRUE, trueRefetched.getBooleanColumn());
+
+        // fetch false
+        Expression falseQ = ExpressionFactory.matchExp("booleanColumn", Boolean.FALSE);
+        List<?> falseResult = context1.performQuery(new SelectQuery(
+                BooleanTestEntity.class,
+                falseQ));
+        assertEquals(1, falseResult.size());
+
+        BooleanTestEntity falseRefetched = (BooleanTestEntity) falseResult.get(0);
+        assertEquals(Boolean.FALSE, falseRefetched.getBooleanColumn());
+
+        // CAY-320. Simplifying the use of booleans to allow identity comparison.
+        assertNotSame(falseRefetched, falseObject);
+        assertSame(Boolean.FALSE, falseRefetched.getBooleanColumn());
+    }
+
+    public void testDecimalPK() throws Exception {
+
+        // populate (testing insert as well)
+        DecimalPKTestEntity object = context.newObject(DecimalPKTestEntity.class);
+
+        object.setName("o1");
+        object.setDecimalPK(new BigDecimal("1.25"));
+        context.commitChanges();
+
+        ObjectId syntheticId = new ObjectId(
+                "DecimalPKTestEntity",
+                "DECIMAL_PK",
+                new BigDecimal("1.25"));
+        assertSame(object, context.getGraphManager().getNode(syntheticId));
+
+        context.deleteObjects(object);
+        context.commitChanges();
+    }
+
+    public void testDecimalPK1() throws Exception {
+
+        // populate (testing insert as well)
+        DecimalPKTest1 object = context.newObject(DecimalPKTest1.class);
+
+        object.setName("o2");
+        object.setDecimalPK(new Double(1.25));
+        context.commitChanges();
+
+        ObjectId syntheticId = new ObjectId("DecimalPKTest1", "DECIMAL_PK", new Double(
+                1.25));
+        assertSame(object, context.getGraphManager().getNode(syntheticId));
+    }
+}