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

[07/48] Installing Maven Failsafe Plugin

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/map/ObjEntityTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/map/ObjEntityTest.java b/cayenne-server/src/test/java/org/apache/cayenne/map/ObjEntityTest.java
deleted file mode 100644
index 8929e05..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/map/ObjEntityTest.java
+++ /dev/null
@@ -1,431 +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.map;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.cayenne.CayenneDataObject;
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.ObjectContext;
-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.exp.parser.ASTObjPath;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.testdo.testmap.Artist;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-import org.apache.cayenne.util.Util;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class ObjEntityTest extends ServerCase {
-
-    @Inject
-    private ObjectContext context;
-
-    @Inject
-    private ServerRuntime runtime;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("PAINTING_INFO");
-        dbHelper.deleteAll("PAINTING");
-        dbHelper.deleteAll("ARTIST_EXHIBIT");
-        dbHelper.deleteAll("ARTIST_GROUP");
-        dbHelper.deleteAll("ARTIST");
-    }
-
-    public void testGetAttributeWithOverrides() {
-
-        DataMap map = new DataMap("dm");
-
-        ObjEntity superEntity = new ObjEntity("super");
-        superEntity.addAttribute(new ObjAttribute("a1", "int", superEntity));
-        superEntity.addAttribute(new ObjAttribute("a2", "int", superEntity));
-
-        map.addObjEntity(superEntity);
-
-        ObjEntity subEntity = new ObjEntity("sub");
-        subEntity.setSuperEntityName(superEntity.getName());
-        subEntity.addAttributeOverride("a1", "overridden.path");
-        subEntity.addAttribute(new ObjAttribute("a3", "int", subEntity));
-
-        map.addObjEntity(subEntity);
-
-        ObjAttribute a1 = subEntity.getAttribute("a1");
-        assertNotNull(a1);
-        assertSame(subEntity, a1.getEntity());
-        assertEquals("overridden.path", a1.getDbAttributePath());
-        assertEquals("int", a1.getType());
-
-        ObjAttribute a2 = subEntity.getAttribute("a2");
-        assertNotNull(a2);
-        assertSame(subEntity, a2.getEntity());
-        assertNull(a2.getDbAttributePath());
-
-        ObjAttribute a3 = subEntity.getAttribute("a3");
-        assertNotNull(a3);
-        assertSame(subEntity, a3.getEntity());
-    }
-
-    public void testGetPrimaryKeys() {
-        ObjEntity artistE = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
-        Collection<ObjAttribute> pks = artistE.getPrimaryKeys();
-        assertEquals(1, pks.size());
-
-        ObjAttribute pk = pks.iterator().next();
-        assertEquals("java.lang.Long", pk.getType());
-        assertEquals("ARTIST_ID", pk.getDbAttributePath());
-        assertEquals("artistId", pk.getName());
-        assertNull(pk.getEntity());
-        assertFalse(artistE.getAttributes().contains(pk));
-
-        ObjEntity clientArtistE = artistE.getClientEntity();
-        Collection<ObjAttribute> clientpks = clientArtistE.getPrimaryKeys();
-        assertEquals(1, clientpks.size());
-        ObjAttribute clientPk = clientpks.iterator().next();
-        assertEquals("java.lang.Long", clientPk.getType());
-        assertEquals("ARTIST_ID", clientPk.getDbAttributePath());
-        assertEquals("artistId", clientPk.getName());
-        assertNull(clientPk.getEntity());
-        assertFalse(clientArtistE.getAttributes().contains(pk));
-
-        ObjEntity meaningfulPKE = runtime.getDataDomain().getEntityResolver().getObjEntity("MeaningfulPKTest1");
-        Collection<ObjAttribute> mpks = meaningfulPKE.getPrimaryKeys();
-        assertEquals(1, mpks.size());
-
-        ObjAttribute mpk = mpks.iterator().next();
-        assertTrue(meaningfulPKE.getAttributes().contains(mpk));
-
-        ObjEntity clientMeaningfulPKE = meaningfulPKE.getClientEntity();
-        Collection<ObjAttribute> clientmpks = clientMeaningfulPKE.getPrimaryKeys();
-        assertEquals(1, clientmpks.size());
-
-        ObjAttribute clientmpk = clientmpks.iterator().next();
-        assertEquals("java.lang.Integer", clientmpk.getType());
-        assertTrue(clientMeaningfulPKE.getAttributes().contains(clientmpk));
-    }
-
-    public void testAttributes() {
-        ObjEntity artistE = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
-        ObjAttribute attr = artistE.getAttribute("artistName");
-
-        assertEquals(attr.getMaxLength(), attr.getDbAttribute().getMaxLength());
-        assertEquals(attr.isMandatory(), attr.getDbAttribute().isMandatory());
-    }
-
-    public void testLastPathComponent() {
-        ObjEntity artistE = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
-
-        Map<String, String> aliases = new HashMap<String, String>();
-        aliases.put("a", "paintingArray.toGallery");
-
-        PathComponent<ObjAttribute, ObjRelationship> lastAttribute = artistE.lastPathComponent(
-                Expression.fromString("paintingArray.paintingTitle"), aliases);
-        assertTrue(lastAttribute.getAttribute() != null);
-        assertEquals("paintingTitle", lastAttribute.getAttribute().getName());
-
-        PathComponent<ObjAttribute, ObjRelationship> lastRelationship = artistE.lastPathComponent(
-                Expression.fromString("paintingArray.toGallery"), aliases);
-        assertTrue(lastRelationship.getRelationship() != null);
-        assertEquals("toGallery", lastRelationship.getRelationship().getName());
-
-        PathComponent<ObjAttribute, ObjRelationship> lastLeftJoinRelationship = artistE.lastPathComponent(
-                new ASTObjPath("paintingArray+.toGallery+"), aliases);
-        assertTrue(lastLeftJoinRelationship.getRelationship() != null);
-        assertEquals("toGallery", lastLeftJoinRelationship.getRelationship().getName());
-
-        PathComponent<ObjAttribute, ObjRelationship> lastAliasedRelationship = artistE.lastPathComponent(
-                new ASTObjPath("a"), aliases);
-        assertTrue(lastAliasedRelationship.getRelationship() != null);
-        assertEquals("toGallery", lastAliasedRelationship.getRelationship().getName());
-    }
-
-    public void testGeneric() {
-        ObjEntity e1 = new ObjEntity("e1");
-        assertTrue(e1.isGeneric());
-
-        e1.setClassName("SomeClass");
-        assertFalse(e1.isGeneric());
-
-        DataMap m = new DataMap("X");
-        m.setDefaultSuperclass("SomeClass");
-        m.addObjEntity(e1);
-
-        assertTrue(e1.isGeneric());
-
-        e1.setClassName("SomeOtherClass");
-        assertFalse(e1.isGeneric());
-
-        e1.setClassName(CayenneDataObject.class.getName());
-        assertTrue(e1.isGeneric());
-    }
-
-    public void testServerOnly() {
-        ObjEntity e1 = new ObjEntity("e1");
-
-        assertFalse(e1.isServerOnly());
-        e1.setServerOnly(true);
-        assertTrue(e1.isServerOnly());
-    }
-
-    public void testClientAllowed() {
-        ObjEntity e1 = new ObjEntity("e1");
-
-        assertFalse("No parent DataMap should have automatically disabled client.", e1.isClientAllowed());
-
-        DataMap map = new DataMap("m1");
-        e1.setDataMap(map);
-
-        assertFalse(e1.isClientAllowed());
-
-        map.setClientSupported(true);
-        assertTrue(e1.isClientAllowed());
-
-        e1.setServerOnly(true);
-        assertFalse(e1.isClientAllowed());
-    }
-
-    public void testGetPrimaryKeyNames() {
-        ObjEntity entity = new ObjEntity("entity");
-        DbEntity dbentity = new DbEntity("dbe");
-
-        // need a container
-        DataMap dataMap = new DataMap();
-        dataMap.addObjEntity(entity);
-        dataMap.addDbEntity(dbentity);
-        entity.setDbEntity(dbentity);
-
-        // Test correctness with no mapped PK.
-        assertEquals(0, entity.getPrimaryKeyNames().size());
-
-        // Add a single column PK to the DB entity.
-        DbAttribute pk = new DbAttribute();
-        pk.setName("id");
-        pk.setPrimaryKey(true);
-        dbentity.addAttribute(pk);
-
-        // Test correctness with a single column PK.
-        assertEquals(1, entity.getPrimaryKeyNames().size());
-        assertTrue(entity.getPrimaryKeyNames().contains(pk.getName()));
-
-        // Add a multi-column PK to the DB entity.
-        DbAttribute pk2 = new DbAttribute();
-        pk2.setName("id2");
-        pk2.setPrimaryKey(true);
-        dbentity.addAttribute(pk2);
-
-        // Test correctness with a multi-column PK.
-        assertEquals(2, entity.getPrimaryKeyNames().size());
-        assertTrue(entity.getPrimaryKeyNames().contains(pk.getName()));
-        assertTrue(entity.getPrimaryKeyNames().contains(pk2.getName()));
-    }
-
-    public void testGetClientEntity() {
-
-        DataMap map = new DataMap();
-        map.setClientSupported(true);
-
-        final ObjEntity target = new ObjEntity("te1");
-        map.addObjEntity(target);
-
-        ObjEntity e1 = new ObjEntity("entity");
-        e1.setClassName("x.y.z");
-        e1.setClientClassName("a.b.c");
-        e1.addAttribute(new ObjAttribute("A1"));
-        e1.addAttribute(new ObjAttribute("A2"));
-        map.addObjEntity(e1);
-
-        DbEntity dbentity = new DbEntity("dbe");
-        map.addDbEntity(dbentity);
-        e1.setDbEntity(dbentity);
-
-        ObjRelationship r1 = new ObjRelationship("r1") {
-
-            @Override
-            public ObjEntity getTargetEntity() {
-                return target;
-            }
-        };
-
-        e1.addRelationship(r1);
-
-        ObjEntity e2 = e1.getClientEntity();
-        assertNotNull(e2);
-        assertEquals(e1.getName(), e2.getName());
-        assertEquals(e1.getClientClassName(), e2.getClassName());
-        assertEquals(e1.getAttributes().size(), e2.getAttributes().size());
-        assertEquals(e1.getRelationships().size(), e2.getRelationships().size());
-    }
-
-    public void testSerializability() throws Exception {
-        ObjEntity entity = new ObjEntity("entity");
-
-        ObjEntity d1 = Util.cloneViaSerialization(entity);
-        assertEquals(entity.getName(), d1.getName());
-    }
-
-    public void testDbEntityName() {
-        ObjEntity entity = new ObjEntity("entity");
-        assertNull(entity.getDbEntityName());
-
-        entity.setDbEntityName("dbe");
-        assertEquals("dbe", entity.getDbEntityName());
-
-        entity.setDbEntityName(null);
-        assertNull(entity.getDbEntityName());
-    }
-
-    public void testDbEntity() {
-        ObjEntity entity = new ObjEntity("entity");
-        DbEntity dbentity = new DbEntity("dbe");
-
-        // need a container
-        DataMap dataMap = new DataMap();
-        dataMap.addObjEntity(entity);
-        dataMap.addDbEntity(dbentity);
-
-        assertNull(entity.getDbEntity());
-
-        entity.setDbEntity(dbentity);
-        assertSame(dbentity, entity.getDbEntity());
-
-        entity.setDbEntity(null);
-        assertNull(entity.getDbEntity());
-
-        entity.setDbEntityName("dbe");
-        assertSame(dbentity, entity.getDbEntity());
-    }
-
-    public void testDbEntityNoContainer() {
-        ObjEntity entity = new ObjEntity("entity");
-        entity.setDbEntityName("dbe");
-
-        try {
-            entity.getDbEntity();
-            fail("Without a container ObjENtity shouldn't resolve DbEntity");
-        } catch (CayenneRuntimeException ex) {
-            // expected
-        }
-    }
-
-    public void testClassName() {
-        ObjEntity entity = new ObjEntity("entity");
-        String tstName = "tst_name";
-        entity.setClassName(tstName);
-        assertEquals(tstName, entity.getClassName());
-    }
-
-    public void testSuperClassName() {
-        ObjEntity entity = new ObjEntity("entity");
-        String tstName = "super_tst_name";
-        entity.setSuperClassName(tstName);
-        assertEquals(tstName, entity.getSuperClassName());
-    }
-
-    public void testAttributeForDbAttribute() throws Exception {
-        ObjEntity ae = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
-        DbEntity dae = ae.getDbEntity();
-
-        assertNull(ae.getAttributeForDbAttribute(dae.getAttribute("ARTIST_ID")));
-        assertNotNull(ae.getAttributeForDbAttribute(dae.getAttribute("ARTIST_NAME")));
-    }
-
-    public void testRelationshipForDbRelationship() throws Exception {
-        ObjEntity ae = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
-        DbEntity dae = ae.getDbEntity();
-
-        assertNull(ae.getRelationshipForDbRelationship(new DbRelationship()));
-        assertNotNull(ae.getRelationshipForDbRelationship(dae.getRelationship("paintingArray")));
-    }
-
-    public void testReadOnly() throws Exception {
-        ObjEntity entity = new ObjEntity("entity");
-        assertFalse(entity.isReadOnly());
-        entity.setReadOnly(true);
-        assertTrue(entity.isReadOnly());
-    }
-
-    public void testTranslateToRelatedEntityIndependentPath() throws Exception {
-        ObjEntity artistE = runtime.getDataDomain().getEntityResolver().getObjEntity(Artist.class);
-
-        Expression e1 = Expression.fromString("paintingArray");
-        Expression translated = artistE.translateToRelatedEntity(e1, "artistExhibitArray");
-        assertEquals("failure: " + translated, Expression.fromString("db:toArtist.paintingArray"), translated);
-    }
-
-    public void testTranslateToRelatedEntityTrimmedPath() throws Exception {
-        ObjEntity artistE = runtime.getDataDomain().getEntityResolver().getObjEntity(Artist.class);
-
-        Expression e1 = Expression.fromString("artistExhibitArray.toExhibit");
-        Expression translated = artistE.translateToRelatedEntity(e1, "artistExhibitArray");
-        assertEquals("failure: " + translated, Expression.fromString("db:toArtist.artistExhibitArray.toExhibit"),
-                translated);
-    }
-
-    public void testTranslateToRelatedEntitySplitHalfWay() throws Exception {
-        ObjEntity artistE = runtime.getDataDomain().getEntityResolver().getObjEntity(Artist.class);
-
-        Expression e1 = Expression.fromString("paintingArray.toPaintingInfo.textReview");
-        Expression translated = artistE.translateToRelatedEntity(e1, "paintingArray.toGallery");
-        assertEquals("failure: " + translated,
-                Expression.fromString("db:paintingArray.toArtist.paintingArray.toPaintingInfo.TEXT_REVIEW"), translated);
-    }
-
-    public void testTranslateToRelatedEntityMatchingPath() throws Exception {
-        ObjEntity artistE = runtime.getDataDomain().getEntityResolver().getObjEntity(Artist.class);
-        Expression e1 = Expression.fromString("artistExhibitArray.toExhibit");
-        Expression translated = artistE.translateToRelatedEntity(e1, "artistExhibitArray.toExhibit");
-        assertEquals("failure: " + translated,
-                Expression.fromString("db:artistExhibitArray.toArtist.artistExhibitArray.toExhibit"), translated);
-    }
-
-    public void testTranslateToRelatedEntityMultiplePaths() throws Exception {
-        ObjEntity artistE = runtime.getDataDomain().getEntityResolver().getObjEntity(Artist.class);
-
-        Expression e1 = Expression.fromString("paintingArray = $p and artistExhibitArray.toExhibit.closingDate = $d");
-        Expression translated = artistE.translateToRelatedEntity(e1, "artistExhibitArray");
-        assertEquals("failure: " + translated, Expression.fromString("db:toArtist.paintingArray = $p "
-                + "and db:toArtist.artistExhibitArray.toExhibit.CLOSING_DATE = $d"), translated);
-    }
-    
-    public void testTranslateToRelatedEntityOuterJoin_Flattened() throws Exception {
-        ObjEntity artistE = runtime.getDataDomain().getEntityResolver().getObjEntity(Artist.class);
-
-        Expression e1 = Expression.fromString("groupArray+.name");
-        Expression translated = artistE.translateToRelatedEntity(e1, "artistExhibitArray");
-        assertEquals("failure: " + translated, Expression.fromString("db:toArtist.artistGroupArray+.toGroup+.NAME"), translated);
-    }
-
-    public void testTranslateNullArg() {
-        ObjEntity entity = context.getEntityResolver().getObjEntity("Artist");
-
-        Expression exp = ExpressionFactory.noMatchExp("dateOfBirth", null);
-        Expression translated = entity.translateToDbPath(exp);
-
-        assertFalse(translated.match(new Artist()));
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/map/ObjRelationshipIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/map/ObjRelationshipIT.java b/cayenne-server/src/test/java/org/apache/cayenne/map/ObjRelationshipIT.java
new file mode 100644
index 0000000..783481f
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/map/ObjRelationshipIT.java
@@ -0,0 +1,495 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.map;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.configuration.DataMapLoader;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.ExpressionException;
+import org.apache.cayenne.resource.URLResource;
+import org.apache.cayenne.testdo.inheritance.vertical.Iv2Sub1;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.apache.cayenne.util.Util;
+import org.apache.cayenne.util.XMLEncoder;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URL;
+import java.util.Collections;
+import java.util.List;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class ObjRelationshipIT extends ServerCase {
+
+    @Inject
+    private ServerRuntime runtime;
+
+    private DbEntity artistDBEntity;
+    private DbEntity artistExhibitDBEntity;
+    private DbEntity exhibitDBEntity;
+    private DbEntity paintingDbEntity;
+    private DbEntity galleryDBEntity;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        EntityResolver resolver = runtime.getDataDomain().getEntityResolver();
+
+        artistDBEntity = resolver.getDbEntity("ARTIST");
+        artistExhibitDBEntity = resolver.getDbEntity("ARTIST_EXHIBIT");
+        exhibitDBEntity = resolver.getDbEntity("EXHIBIT");
+        paintingDbEntity = resolver.getDbEntity("PAINTING");
+        galleryDBEntity = resolver.getDbEntity("GALLERY");
+    }
+
+    public void testEncodeAsXML() {
+        StringWriter buffer = new StringWriter();
+        PrintWriter out = new PrintWriter(buffer);
+        XMLEncoder encoder = new XMLEncoder(out);
+
+        DataMap map = new DataMap("M");
+        ObjEntity source = new ObjEntity("S");
+        ObjEntity target = new ObjEntity("T");
+        map.addObjEntity(source);
+        map.addObjEntity(target);
+
+        ObjRelationship r = new ObjRelationship("X");
+        r.setSourceEntity(source);
+        r.setTargetEntityName("T");
+        r.setCollectionType("java.util.Map");
+        r.setMapKey("bla");
+
+        r.encodeAsXML(encoder);
+        out.close();
+
+        String lineBreak = System.getProperty("line.separator");
+
+        assertEquals("<obj-relationship name=\"X\" source=\"S\" target=\"T\" "
+                + "collection-type=\"java.util.Map\" map-key=\"bla\"/>" + lineBreak, buffer.getBuffer().toString());
+    }
+
+    public void testCollectionType() {
+        ObjRelationship r = new ObjRelationship("X");
+        assertNull(r.getCollectionType());
+        r.setCollectionType("java.util.Map");
+        assertEquals("java.util.Map", r.getCollectionType());
+    }
+
+    public void testSerializability() throws Exception {
+        ObjEntity artistObjEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
+
+        // start with "to many"
+        ObjRelationship r1 = artistObjEnt.getRelationship("paintingArray");
+
+        ObjRelationship r2 = Util.cloneViaSerialization(r1);
+        assertEquals(r1.getName(), r2.getName());
+        assertEquals(r1.getDbRelationshipPath(), r2.getDbRelationshipPath());
+    }
+
+    public void testGetClientRelationship() {
+        final ObjEntity target = new ObjEntity("te1");
+        ObjRelationship r1 = new ObjRelationship("r1") {
+
+            @Override
+            public ObjEntity getTargetEntity() {
+                return target;
+            }
+        };
+
+        r1.setDeleteRule(DeleteRule.DENY);
+        r1.setTargetEntityName("te1");
+
+        ObjRelationship r2 = r1.getClientRelationship();
+        assertNotNull(r2);
+        assertEquals(r1.getName(), r2.getName());
+        assertEquals(r1.getTargetEntityName(), r2.getTargetEntityName());
+        assertEquals(r1.getDeleteRule(), r2.getDeleteRule());
+    }
+
+    public void testGetReverseDbRelationshipPath() {
+        ObjEntity artistObjEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
+        ObjEntity paintingObjEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Painting");
+
+        // start with "to many"
+        ObjRelationship r1 = artistObjEnt.getRelationship("paintingArray");
+
+        assertEquals("toArtist", r1.getReverseDbRelationshipPath());
+
+        ObjRelationship r2 = paintingObjEnt.getRelationship("toArtist");
+
+        assertEquals("paintingArray", r2.getReverseDbRelationshipPath());
+    }
+
+    public void testSetDbRelationshipPath() {
+        ObjEntity artistObjEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
+
+        ObjRelationship r = new ObjRelationship("r");
+        r.setSourceEntity(artistObjEnt);
+        r.setDbRelationshipPath("paintingArray");
+        assertEquals(r.getDbRelationshipPath(), "paintingArray");
+    }
+
+    public void testRefreshFromPath() {
+        ObjRelationship relationship = new ObjRelationship();
+
+        // attempt to resolve must fail - relationship is outside of context,
+        // plus the path is random
+        try {
+            relationship.setDbRelationshipPath("dummy.path");
+            fail("set random path should have failed.");
+        } catch (CayenneRuntimeException ex) {
+            // expected
+        }
+
+        DataMap map = new DataMap();
+        ObjEntity entity = new ObjEntity("Test");
+        map.addObjEntity(entity);
+
+        relationship.setSourceEntity(entity);
+        // attempt to resolve must fail - relationship is outside of context,
+        // plus the path is random
+        try {
+            relationship.refreshFromPath("dummy.path", false);
+            fail("refresh over a dummy path should have failed.");
+        } catch (ExpressionException ex) {
+            // expected
+        }
+
+        // finally assemble ObjEntity to make the path valid
+        DbEntity dbEntity1 = new DbEntity("TEST1");
+        DbEntity dbEntity2 = new DbEntity("TEST2");
+        DbEntity dbEntity3 = new DbEntity("TEST3");
+        map.addDbEntity(dbEntity1);
+        map.addDbEntity(dbEntity2);
+        map.addDbEntity(dbEntity3);
+        entity.setDbEntityName("TEST1");
+        DbRelationship dummyR = new DbRelationship("dummy");
+        dummyR.setTargetEntityName("TEST2");
+        dummyR.setSourceEntity(dbEntity1);
+        DbRelationship pathR = new DbRelationship("path");
+        pathR.setTargetEntityName("TEST3");
+        pathR.setSourceEntity(dbEntity2);
+        dbEntity1.addRelationship(dummyR);
+        dbEntity2.addRelationship(pathR);
+
+        relationship.refreshFromPath("dummy.path", false);
+
+        List<DbRelationship> resolvedPath = relationship.getDbRelationships();
+        assertEquals(2, resolvedPath.size());
+        assertSame(dummyR, resolvedPath.get(0));
+        assertSame(pathR, resolvedPath.get(1));
+    }
+
+    public void testCalculateToMany() {
+        // assemble fixture....
+        DataMap map = new DataMap();
+        ObjEntity entity = new ObjEntity("Test");
+        map.addObjEntity(entity);
+
+        DbEntity dbEntity1 = new DbEntity("TEST1");
+        DbEntity dbEntity2 = new DbEntity("TEST2");
+        DbEntity dbEntity3 = new DbEntity("TEST3");
+        map.addDbEntity(dbEntity1);
+        map.addDbEntity(dbEntity2);
+        map.addDbEntity(dbEntity3);
+        entity.setDbEntityName("TEST1");
+        DbRelationship dummyR = new DbRelationship("dummy");
+        dummyR.setTargetEntityName("TEST2");
+        dummyR.setSourceEntity(dbEntity1);
+        DbRelationship pathR = new DbRelationship("path");
+        pathR.setTargetEntityName("TEST3");
+        pathR.setSourceEntity(dbEntity2);
+        dbEntity1.addRelationship(dummyR);
+        dbEntity2.addRelationship(pathR);
+
+        ObjRelationship relationship = new ObjRelationship();
+        relationship.setSourceEntity(entity);
+
+        // test how toMany changes dependending on the underlying
+        // DbRelationships
+        // add DbRelationships directly to avoid events to test
+        // "calculateToMany"
+        relationship.dbRelationships.add(dummyR);
+        assertFalse(relationship.isToMany());
+
+        dummyR.setToMany(true);
+        relationship.recalculateToManyValue();
+        assertTrue(relationship.isToMany());
+
+        dummyR.setToMany(false);
+        relationship.recalculateToManyValue();
+        assertFalse(relationship.isToMany());
+
+        // test chain
+        relationship.dbRelationships.add(pathR);
+        assertFalse(relationship.isToMany());
+
+        pathR.setToMany(true);
+        relationship.recalculateToManyValue();
+        assertTrue(relationship.isToMany());
+    }
+
+    public void testCalculateToManyFromPath() {
+        // assemble fixture....
+        DataMap map = new DataMap();
+        ObjEntity entity = new ObjEntity("Test");
+        map.addObjEntity(entity);
+
+        DbEntity dbEntity1 = new DbEntity("TEST1");
+        DbEntity dbEntity2 = new DbEntity("TEST2");
+        DbEntity dbEntity3 = new DbEntity("TEST3");
+        map.addDbEntity(dbEntity1);
+        map.addDbEntity(dbEntity2);
+        map.addDbEntity(dbEntity3);
+        entity.setDbEntityName("TEST1");
+        DbRelationship dummyR = new DbRelationship("dummy");
+        dummyR.setTargetEntityName("TEST2");
+        dummyR.setSourceEntity(dbEntity1);
+        DbRelationship pathR = new DbRelationship("path");
+        pathR.setTargetEntityName("TEST3");
+        pathR.setSourceEntity(dbEntity2);
+        dbEntity1.addRelationship(dummyR);
+        dbEntity2.addRelationship(pathR);
+
+        ObjRelationship relationship = new ObjRelationship();
+        relationship.setSourceEntity(entity);
+
+        // test how toMany changes when the path is set as a string
+
+        relationship.setDbRelationshipPath("dummy");
+        assertFalse(relationship.isToMany());
+
+        dummyR.setToMany(true);
+        relationship.setDbRelationshipPath(null);
+        relationship.setDbRelationshipPath("dummy");
+        assertTrue(relationship.isToMany());
+
+        dummyR.setToMany(false);
+        relationship.setDbRelationshipPath(null);
+        relationship.setDbRelationshipPath("dummy");
+        assertFalse(relationship.isToMany());
+
+        // test chain
+        relationship.setDbRelationshipPath(null);
+        relationship.setDbRelationshipPath("dummy.path");
+        assertFalse(relationship.isToMany());
+
+        pathR.setToMany(true);
+        relationship.setDbRelationshipPath(null);
+        relationship.setDbRelationshipPath("dummy.path");
+        assertTrue(relationship.isToMany());
+    }
+
+    public void testTargetEntity() throws Exception {
+        ObjRelationship relationship = new ObjRelationship("some_rel");
+        relationship.setTargetEntityName("targ");
+
+        try {
+            relationship.getTargetEntity();
+            fail("Without a container, getTargetEntity() must fail.");
+        } catch (CayenneRuntimeException ex) {
+            // expected
+        }
+
+        // assemble container
+        DataMap map = new DataMap();
+        ObjEntity src = new ObjEntity("src");
+        map.addObjEntity(src);
+
+        src.addRelationship(relationship);
+        assertNull(relationship.getTargetEntity());
+
+        ObjEntity target = new ObjEntity("targ");
+        map.addObjEntity(target);
+
+        assertSame(target, relationship.getTargetEntity());
+    }
+
+    public void testGetReverseRel1() {
+
+        ObjEntity artistObjEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
+        ObjEntity paintingObjEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Painting");
+
+        // start with "to many"
+        ObjRelationship r1 = artistObjEnt.getRelationship("paintingArray");
+        ObjRelationship r2 = r1.getReverseRelationship();
+
+        assertNotNull(r2);
+        assertSame(paintingObjEnt.getRelationship("toArtist"), r2);
+    }
+
+    public void testGetReverseRel2() {
+        ObjEntity artistEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
+        ObjEntity paintingEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Painting");
+
+        // start with "to one"
+        ObjRelationship r1 = paintingEnt.getRelationship("toArtist");
+        ObjRelationship r2 = r1.getReverseRelationship();
+
+        assertNotNull(r2);
+        assertSame(artistEnt.getRelationship("paintingArray"), r2);
+    }
+
+    public void testSingleDbRelationship() {
+        ObjRelationship relationship = new ObjRelationship();
+        DbRelationship r1 = new DbRelationship("X");
+        relationship.addDbRelationship(r1);
+        assertEquals(1, relationship.getDbRelationships().size());
+        assertEquals(r1, relationship.getDbRelationships().get(0));
+        assertFalse(relationship.isFlattened());
+        assertFalse(relationship.isReadOnly());
+        assertEquals(r1.isToMany(), relationship.isToMany());
+        relationship.removeDbRelationship(r1);
+        assertEquals(0, relationship.getDbRelationships().size());
+    }
+
+    public void testFlattenedRelationship() {
+        DbRelationship r1 = new DbRelationship("X");
+        DbRelationship r2 = new DbRelationship("Y");
+
+        r1.setSourceEntity(artistDBEntity);
+        r1.setTargetEntity(artistExhibitDBEntity);
+        r1.setToMany(true);
+
+        r2.setSourceEntity(artistExhibitDBEntity);
+        r2.setTargetEntity(exhibitDBEntity);
+        r2.setToMany(false);
+
+        ObjRelationship relationship = new ObjRelationship();
+        relationship.addDbRelationship(r1);
+        relationship.addDbRelationship(r2);
+        assertTrue(relationship.isToMany());
+        assertEquals(2, relationship.getDbRelationships().size());
+        assertEquals(r1, relationship.getDbRelationships().get(0));
+        assertEquals(r2, relationship.getDbRelationships().get(1));
+
+        assertTrue(relationship.isFlattened());
+
+        relationship.removeDbRelationship(r1);
+        assertFalse(relationship.isToMany()); // only remaining rel is r2... a
+                                              // toOne
+        assertEquals(1, relationship.getDbRelationships().size());
+        assertEquals(r2, relationship.getDbRelationships().get(0));
+        assertFalse(relationship.isFlattened());
+        assertFalse(relationship.isReadOnly());
+
+    }
+
+    public void testReadOnly_Flattened1_1__N_1() {
+
+        // check common vertical inheritance relationships
+
+        DataMapLoader loader = runtime.getInjector().getInstance(DataMapLoader.class);
+        URL url = getClass().getClassLoader().getResource("inheritance-vertical.map.xml");
+        DataMap dataMap = loader.load(new URLResource(url));
+        EntityResolver resolver = new EntityResolver(Collections.singleton(dataMap));
+
+        ObjEntity iv2Sub1 = resolver.getObjEntity(Iv2Sub1.class);
+        ObjRelationship x = iv2Sub1.getRelationship(Iv2Sub1.X_PROPERTY);
+        assertTrue(x.isFlattened());
+        assertFalse(x.isReadOnly());
+    }
+
+    public void testReadOnlyMoreThan3DbRelsRelationship() {
+        // Readonly is a flattened relationship that isn't over a single
+        // many->many link
+        // table
+        DbRelationship r1 = new DbRelationship("X");
+        DbRelationship r2 = new DbRelationship("Y");
+        DbRelationship r3 = new DbRelationship("Z");
+
+        r1.setSourceEntity(artistDBEntity);
+        r1.setTargetEntity(artistExhibitDBEntity);
+        r1.setToMany(true);
+        r2.setSourceEntity(artistExhibitDBEntity);
+        r2.setTargetEntity(exhibitDBEntity);
+        r2.setToMany(false);
+        r3.setSourceEntity(exhibitDBEntity);
+        r3.setTargetEntity(galleryDBEntity);
+        r3.setToMany(false);
+
+        ObjRelationship relationship = new ObjRelationship();
+        relationship.addDbRelationship(r1);
+        relationship.addDbRelationship(r2);
+        relationship.addDbRelationship(r3);
+
+        assertTrue(relationship.isFlattened());
+        assertTrue(relationship.isReadOnly());
+        assertTrue(relationship.isToMany());
+
+    }
+
+    // Test for a read-only flattened relationship that is readonly because it's
+    // dbrel
+    // sequence is "incorrect" (or rather, unsupported)
+    public void testIncorrectSequenceReadOnlyRelationship() {
+        DbRelationship r1 = new DbRelationship("X");
+        DbRelationship r2 = new DbRelationship("Y");
+
+        r1.setSourceEntity(artistDBEntity);
+        r1.setTargetEntity(paintingDbEntity);
+        r1.setToMany(true);
+        r2.setSourceEntity(paintingDbEntity);
+        r2.setTargetEntity(galleryDBEntity);
+        r2.setToMany(false);
+
+        ObjRelationship relationship = new ObjRelationship();
+        relationship.addDbRelationship(r1);
+        relationship.addDbRelationship(r2);
+
+        assertTrue(relationship.isFlattened());
+        assertTrue(relationship.isReadOnly());
+        assertTrue(relationship.isToMany());
+    }
+
+    // Test a relationship loaded from the test datamap that we know should be
+    // flattened
+    public void testKnownFlattenedRelationship() {
+        ObjEntity artistEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
+        ObjRelationship theRel = artistEnt.getRelationship("groupArray");
+        assertNotNull(theRel);
+        assertTrue(theRel.isFlattened());
+        assertFalse(theRel.isReadOnly());
+    }
+
+    public void testBadDeleteRuleValue() {
+        ObjRelationship relationship = new ObjRelationship();
+
+        try {
+            relationship.setDeleteRule(999);
+            fail("Should have failed with IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Good... it should throw an exception
+        }
+    }
+
+    public void testOkDeleteRuleValue() {
+        ObjRelationship relationship = new ObjRelationship();
+        try {
+            relationship.setDeleteRule(DeleteRule.CASCADE);
+            relationship.setDeleteRule(DeleteRule.DENY);
+            relationship.setDeleteRule(DeleteRule.NULLIFY);
+        } catch (IllegalArgumentException e) {
+            e.printStackTrace();
+            fail("Should not have thrown an exception :" + e.getMessage());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/map/ObjRelationshipTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/map/ObjRelationshipTest.java b/cayenne-server/src/test/java/org/apache/cayenne/map/ObjRelationshipTest.java
deleted file mode 100644
index a49555b..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/map/ObjRelationshipTest.java
+++ /dev/null
@@ -1,495 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.map;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.net.URL;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.configuration.DataMapLoader;
-import org.apache.cayenne.configuration.server.ServerRuntime;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.ExpressionException;
-import org.apache.cayenne.resource.URLResource;
-import org.apache.cayenne.testdo.inheritance.vertical.Iv2Sub1;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-import org.apache.cayenne.util.Util;
-import org.apache.cayenne.util.XMLEncoder;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class ObjRelationshipTest extends ServerCase {
-
-    @Inject
-    private ServerRuntime runtime;
-
-    private DbEntity artistDBEntity;
-    private DbEntity artistExhibitDBEntity;
-    private DbEntity exhibitDBEntity;
-    private DbEntity paintingDbEntity;
-    private DbEntity galleryDBEntity;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        EntityResolver resolver = runtime.getDataDomain().getEntityResolver();
-
-        artistDBEntity = resolver.getDbEntity("ARTIST");
-        artistExhibitDBEntity = resolver.getDbEntity("ARTIST_EXHIBIT");
-        exhibitDBEntity = resolver.getDbEntity("EXHIBIT");
-        paintingDbEntity = resolver.getDbEntity("PAINTING");
-        galleryDBEntity = resolver.getDbEntity("GALLERY");
-    }
-
-    public void testEncodeAsXML() {
-        StringWriter buffer = new StringWriter();
-        PrintWriter out = new PrintWriter(buffer);
-        XMLEncoder encoder = new XMLEncoder(out);
-
-        DataMap map = new DataMap("M");
-        ObjEntity source = new ObjEntity("S");
-        ObjEntity target = new ObjEntity("T");
-        map.addObjEntity(source);
-        map.addObjEntity(target);
-
-        ObjRelationship r = new ObjRelationship("X");
-        r.setSourceEntity(source);
-        r.setTargetEntityName("T");
-        r.setCollectionType("java.util.Map");
-        r.setMapKey("bla");
-
-        r.encodeAsXML(encoder);
-        out.close();
-
-        String lineBreak = System.getProperty("line.separator");
-
-        assertEquals("<obj-relationship name=\"X\" source=\"S\" target=\"T\" "
-                + "collection-type=\"java.util.Map\" map-key=\"bla\"/>" + lineBreak, buffer.getBuffer().toString());
-    }
-
-    public void testCollectionType() {
-        ObjRelationship r = new ObjRelationship("X");
-        assertNull(r.getCollectionType());
-        r.setCollectionType("java.util.Map");
-        assertEquals("java.util.Map", r.getCollectionType());
-    }
-
-    public void testSerializability() throws Exception {
-        ObjEntity artistObjEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
-
-        // start with "to many"
-        ObjRelationship r1 = artistObjEnt.getRelationship("paintingArray");
-
-        ObjRelationship r2 = Util.cloneViaSerialization(r1);
-        assertEquals(r1.getName(), r2.getName());
-        assertEquals(r1.getDbRelationshipPath(), r2.getDbRelationshipPath());
-    }
-
-    public void testGetClientRelationship() {
-        final ObjEntity target = new ObjEntity("te1");
-        ObjRelationship r1 = new ObjRelationship("r1") {
-
-            @Override
-            public ObjEntity getTargetEntity() {
-                return target;
-            }
-        };
-
-        r1.setDeleteRule(DeleteRule.DENY);
-        r1.setTargetEntityName("te1");
-
-        ObjRelationship r2 = r1.getClientRelationship();
-        assertNotNull(r2);
-        assertEquals(r1.getName(), r2.getName());
-        assertEquals(r1.getTargetEntityName(), r2.getTargetEntityName());
-        assertEquals(r1.getDeleteRule(), r2.getDeleteRule());
-    }
-
-    public void testGetReverseDbRelationshipPath() {
-        ObjEntity artistObjEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
-        ObjEntity paintingObjEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Painting");
-
-        // start with "to many"
-        ObjRelationship r1 = artistObjEnt.getRelationship("paintingArray");
-
-        assertEquals("toArtist", r1.getReverseDbRelationshipPath());
-
-        ObjRelationship r2 = paintingObjEnt.getRelationship("toArtist");
-
-        assertEquals("paintingArray", r2.getReverseDbRelationshipPath());
-    }
-
-    public void testSetDbRelationshipPath() {
-        ObjEntity artistObjEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
-
-        ObjRelationship r = new ObjRelationship("r");
-        r.setSourceEntity(artistObjEnt);
-        r.setDbRelationshipPath("paintingArray");
-        assertEquals(r.getDbRelationshipPath(), "paintingArray");
-    }
-
-    public void testRefreshFromPath() {
-        ObjRelationship relationship = new ObjRelationship();
-
-        // attempt to resolve must fail - relationship is outside of context,
-        // plus the path is random
-        try {
-            relationship.setDbRelationshipPath("dummy.path");
-            fail("set random path should have failed.");
-        } catch (CayenneRuntimeException ex) {
-            // expected
-        }
-
-        DataMap map = new DataMap();
-        ObjEntity entity = new ObjEntity("Test");
-        map.addObjEntity(entity);
-
-        relationship.setSourceEntity(entity);
-        // attempt to resolve must fail - relationship is outside of context,
-        // plus the path is random
-        try {
-            relationship.refreshFromPath("dummy.path", false);
-            fail("refresh over a dummy path should have failed.");
-        } catch (ExpressionException ex) {
-            // expected
-        }
-
-        // finally assemble ObjEntity to make the path valid
-        DbEntity dbEntity1 = new DbEntity("TEST1");
-        DbEntity dbEntity2 = new DbEntity("TEST2");
-        DbEntity dbEntity3 = new DbEntity("TEST3");
-        map.addDbEntity(dbEntity1);
-        map.addDbEntity(dbEntity2);
-        map.addDbEntity(dbEntity3);
-        entity.setDbEntityName("TEST1");
-        DbRelationship dummyR = new DbRelationship("dummy");
-        dummyR.setTargetEntityName("TEST2");
-        dummyR.setSourceEntity(dbEntity1);
-        DbRelationship pathR = new DbRelationship("path");
-        pathR.setTargetEntityName("TEST3");
-        pathR.setSourceEntity(dbEntity2);
-        dbEntity1.addRelationship(dummyR);
-        dbEntity2.addRelationship(pathR);
-
-        relationship.refreshFromPath("dummy.path", false);
-
-        List<DbRelationship> resolvedPath = relationship.getDbRelationships();
-        assertEquals(2, resolvedPath.size());
-        assertSame(dummyR, resolvedPath.get(0));
-        assertSame(pathR, resolvedPath.get(1));
-    }
-
-    public void testCalculateToMany() {
-        // assemble fixture....
-        DataMap map = new DataMap();
-        ObjEntity entity = new ObjEntity("Test");
-        map.addObjEntity(entity);
-
-        DbEntity dbEntity1 = new DbEntity("TEST1");
-        DbEntity dbEntity2 = new DbEntity("TEST2");
-        DbEntity dbEntity3 = new DbEntity("TEST3");
-        map.addDbEntity(dbEntity1);
-        map.addDbEntity(dbEntity2);
-        map.addDbEntity(dbEntity3);
-        entity.setDbEntityName("TEST1");
-        DbRelationship dummyR = new DbRelationship("dummy");
-        dummyR.setTargetEntityName("TEST2");
-        dummyR.setSourceEntity(dbEntity1);
-        DbRelationship pathR = new DbRelationship("path");
-        pathR.setTargetEntityName("TEST3");
-        pathR.setSourceEntity(dbEntity2);
-        dbEntity1.addRelationship(dummyR);
-        dbEntity2.addRelationship(pathR);
-
-        ObjRelationship relationship = new ObjRelationship();
-        relationship.setSourceEntity(entity);
-
-        // test how toMany changes dependending on the underlying
-        // DbRelationships
-        // add DbRelationships directly to avoid events to test
-        // "calculateToMany"
-        relationship.dbRelationships.add(dummyR);
-        assertFalse(relationship.isToMany());
-
-        dummyR.setToMany(true);
-        relationship.recalculateToManyValue();
-        assertTrue(relationship.isToMany());
-
-        dummyR.setToMany(false);
-        relationship.recalculateToManyValue();
-        assertFalse(relationship.isToMany());
-
-        // test chain
-        relationship.dbRelationships.add(pathR);
-        assertFalse(relationship.isToMany());
-
-        pathR.setToMany(true);
-        relationship.recalculateToManyValue();
-        assertTrue(relationship.isToMany());
-    }
-
-    public void testCalculateToManyFromPath() {
-        // assemble fixture....
-        DataMap map = new DataMap();
-        ObjEntity entity = new ObjEntity("Test");
-        map.addObjEntity(entity);
-
-        DbEntity dbEntity1 = new DbEntity("TEST1");
-        DbEntity dbEntity2 = new DbEntity("TEST2");
-        DbEntity dbEntity3 = new DbEntity("TEST3");
-        map.addDbEntity(dbEntity1);
-        map.addDbEntity(dbEntity2);
-        map.addDbEntity(dbEntity3);
-        entity.setDbEntityName("TEST1");
-        DbRelationship dummyR = new DbRelationship("dummy");
-        dummyR.setTargetEntityName("TEST2");
-        dummyR.setSourceEntity(dbEntity1);
-        DbRelationship pathR = new DbRelationship("path");
-        pathR.setTargetEntityName("TEST3");
-        pathR.setSourceEntity(dbEntity2);
-        dbEntity1.addRelationship(dummyR);
-        dbEntity2.addRelationship(pathR);
-
-        ObjRelationship relationship = new ObjRelationship();
-        relationship.setSourceEntity(entity);
-
-        // test how toMany changes when the path is set as a string
-
-        relationship.setDbRelationshipPath("dummy");
-        assertFalse(relationship.isToMany());
-
-        dummyR.setToMany(true);
-        relationship.setDbRelationshipPath(null);
-        relationship.setDbRelationshipPath("dummy");
-        assertTrue(relationship.isToMany());
-
-        dummyR.setToMany(false);
-        relationship.setDbRelationshipPath(null);
-        relationship.setDbRelationshipPath("dummy");
-        assertFalse(relationship.isToMany());
-
-        // test chain
-        relationship.setDbRelationshipPath(null);
-        relationship.setDbRelationshipPath("dummy.path");
-        assertFalse(relationship.isToMany());
-
-        pathR.setToMany(true);
-        relationship.setDbRelationshipPath(null);
-        relationship.setDbRelationshipPath("dummy.path");
-        assertTrue(relationship.isToMany());
-    }
-
-    public void testTargetEntity() throws Exception {
-        ObjRelationship relationship = new ObjRelationship("some_rel");
-        relationship.setTargetEntityName("targ");
-
-        try {
-            relationship.getTargetEntity();
-            fail("Without a container, getTargetEntity() must fail.");
-        } catch (CayenneRuntimeException ex) {
-            // expected
-        }
-
-        // assemble container
-        DataMap map = new DataMap();
-        ObjEntity src = new ObjEntity("src");
-        map.addObjEntity(src);
-
-        src.addRelationship(relationship);
-        assertNull(relationship.getTargetEntity());
-
-        ObjEntity target = new ObjEntity("targ");
-        map.addObjEntity(target);
-
-        assertSame(target, relationship.getTargetEntity());
-    }
-
-    public void testGetReverseRel1() {
-
-        ObjEntity artistObjEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
-        ObjEntity paintingObjEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Painting");
-
-        // start with "to many"
-        ObjRelationship r1 = artistObjEnt.getRelationship("paintingArray");
-        ObjRelationship r2 = r1.getReverseRelationship();
-
-        assertNotNull(r2);
-        assertSame(paintingObjEnt.getRelationship("toArtist"), r2);
-    }
-
-    public void testGetReverseRel2() {
-        ObjEntity artistEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
-        ObjEntity paintingEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Painting");
-
-        // start with "to one"
-        ObjRelationship r1 = paintingEnt.getRelationship("toArtist");
-        ObjRelationship r2 = r1.getReverseRelationship();
-
-        assertNotNull(r2);
-        assertSame(artistEnt.getRelationship("paintingArray"), r2);
-    }
-
-    public void testSingleDbRelationship() {
-        ObjRelationship relationship = new ObjRelationship();
-        DbRelationship r1 = new DbRelationship("X");
-        relationship.addDbRelationship(r1);
-        assertEquals(1, relationship.getDbRelationships().size());
-        assertEquals(r1, relationship.getDbRelationships().get(0));
-        assertFalse(relationship.isFlattened());
-        assertFalse(relationship.isReadOnly());
-        assertEquals(r1.isToMany(), relationship.isToMany());
-        relationship.removeDbRelationship(r1);
-        assertEquals(0, relationship.getDbRelationships().size());
-    }
-
-    public void testFlattenedRelationship() {
-        DbRelationship r1 = new DbRelationship("X");
-        DbRelationship r2 = new DbRelationship("Y");
-
-        r1.setSourceEntity(artistDBEntity);
-        r1.setTargetEntity(artistExhibitDBEntity);
-        r1.setToMany(true);
-
-        r2.setSourceEntity(artistExhibitDBEntity);
-        r2.setTargetEntity(exhibitDBEntity);
-        r2.setToMany(false);
-
-        ObjRelationship relationship = new ObjRelationship();
-        relationship.addDbRelationship(r1);
-        relationship.addDbRelationship(r2);
-        assertTrue(relationship.isToMany());
-        assertEquals(2, relationship.getDbRelationships().size());
-        assertEquals(r1, relationship.getDbRelationships().get(0));
-        assertEquals(r2, relationship.getDbRelationships().get(1));
-
-        assertTrue(relationship.isFlattened());
-
-        relationship.removeDbRelationship(r1);
-        assertFalse(relationship.isToMany()); // only remaining rel is r2... a
-                                              // toOne
-        assertEquals(1, relationship.getDbRelationships().size());
-        assertEquals(r2, relationship.getDbRelationships().get(0));
-        assertFalse(relationship.isFlattened());
-        assertFalse(relationship.isReadOnly());
-
-    }
-
-    public void testReadOnly_Flattened1_1__N_1() {
-
-        // check common vertical inheritance relationships
-
-        DataMapLoader loader = runtime.getInjector().getInstance(DataMapLoader.class);
-        URL url = getClass().getClassLoader().getResource("inheritance-vertical.map.xml");
-        DataMap dataMap = loader.load(new URLResource(url));
-        EntityResolver resolver = new EntityResolver(Collections.singleton(dataMap));
-
-        ObjEntity iv2Sub1 = resolver.getObjEntity(Iv2Sub1.class);
-        ObjRelationship x = iv2Sub1.getRelationship(Iv2Sub1.X_PROPERTY);
-        assertTrue(x.isFlattened());
-        assertFalse(x.isReadOnly());
-    }
-
-    public void testReadOnlyMoreThan3DbRelsRelationship() {
-        // Readonly is a flattened relationship that isn't over a single
-        // many->many link
-        // table
-        DbRelationship r1 = new DbRelationship("X");
-        DbRelationship r2 = new DbRelationship("Y");
-        DbRelationship r3 = new DbRelationship("Z");
-
-        r1.setSourceEntity(artistDBEntity);
-        r1.setTargetEntity(artistExhibitDBEntity);
-        r1.setToMany(true);
-        r2.setSourceEntity(artistExhibitDBEntity);
-        r2.setTargetEntity(exhibitDBEntity);
-        r2.setToMany(false);
-        r3.setSourceEntity(exhibitDBEntity);
-        r3.setTargetEntity(galleryDBEntity);
-        r3.setToMany(false);
-
-        ObjRelationship relationship = new ObjRelationship();
-        relationship.addDbRelationship(r1);
-        relationship.addDbRelationship(r2);
-        relationship.addDbRelationship(r3);
-
-        assertTrue(relationship.isFlattened());
-        assertTrue(relationship.isReadOnly());
-        assertTrue(relationship.isToMany());
-
-    }
-
-    // Test for a read-only flattened relationship that is readonly because it's
-    // dbrel
-    // sequence is "incorrect" (or rather, unsupported)
-    public void testIncorrectSequenceReadOnlyRelationship() {
-        DbRelationship r1 = new DbRelationship("X");
-        DbRelationship r2 = new DbRelationship("Y");
-
-        r1.setSourceEntity(artistDBEntity);
-        r1.setTargetEntity(paintingDbEntity);
-        r1.setToMany(true);
-        r2.setSourceEntity(paintingDbEntity);
-        r2.setTargetEntity(galleryDBEntity);
-        r2.setToMany(false);
-
-        ObjRelationship relationship = new ObjRelationship();
-        relationship.addDbRelationship(r1);
-        relationship.addDbRelationship(r2);
-
-        assertTrue(relationship.isFlattened());
-        assertTrue(relationship.isReadOnly());
-        assertTrue(relationship.isToMany());
-    }
-
-    // Test a relationship loaded from the test datamap that we know should be
-    // flattened
-    public void testKnownFlattenedRelationship() {
-        ObjEntity artistEnt = runtime.getDataDomain().getEntityResolver().getObjEntity("Artist");
-        ObjRelationship theRel = artistEnt.getRelationship("groupArray");
-        assertNotNull(theRel);
-        assertTrue(theRel.isFlattened());
-        assertFalse(theRel.isReadOnly());
-    }
-
-    public void testBadDeleteRuleValue() {
-        ObjRelationship relationship = new ObjRelationship();
-
-        try {
-            relationship.setDeleteRule(999);
-            fail("Should have failed with IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // Good... it should throw an exception
-        }
-    }
-
-    public void testOkDeleteRuleValue() {
-        ObjRelationship relationship = new ObjRelationship();
-        try {
-            relationship.setDeleteRule(DeleteRule.CASCADE);
-            relationship.setDeleteRule(DeleteRule.DENY);
-            relationship.setDeleteRule(DeleteRule.NULLIFY);
-        } catch (IllegalArgumentException e) {
-            e.printStackTrace();
-            fail("Should not have thrown an exception :" + e.getMessage());
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/merge/AddColumnToModelIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/merge/AddColumnToModelIT.java b/cayenne-server/src/test/java/org/apache/cayenne/merge/AddColumnToModelIT.java
new file mode 100644
index 0000000..db7c086
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/merge/AddColumnToModelIT.java
@@ -0,0 +1,94 @@
+/*****************************************************************
+ *   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.merge;
+
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.ObjAttribute;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.sql.Types;
+import java.util.List;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class AddColumnToModelIT extends MergeCase {
+
+    public void testAddColumn() throws Exception {
+        dropTableIfPresent("NEW_TABLE");
+        assertTokensAndExecute(0, 0);
+
+        DbEntity dbEntity = new DbEntity("NEW_TABLE");
+
+        DbAttribute column1 = new DbAttribute("ID", Types.INTEGER, dbEntity);
+        column1.setMandatory(true);
+        column1.setPrimaryKey(true);
+        dbEntity.addAttribute(column1);
+
+        DbAttribute column2 = new DbAttribute("NAME", Types.VARCHAR, dbEntity);
+        column2.setMaxLength(10);
+        column2.setMandatory(false);
+        dbEntity.addAttribute(column2);
+
+        map.addDbEntity(dbEntity);
+
+        assertTokensAndExecute(1, 0);
+        assertTokensAndExecute(0, 0);
+
+        ObjEntity objEntity = new ObjEntity("NewTable");
+        objEntity.setDbEntity(dbEntity);
+        ObjAttribute oatr1 = new ObjAttribute("name");
+        oatr1.setDbAttributePath(column2.getName());
+        oatr1.setType("java.lang.String");
+        objEntity.addAttribute(oatr1);
+        map.addObjEntity(objEntity);
+
+        // remove name column
+        objEntity.removeAttribute(oatr1.getName());
+        dbEntity.removeAttribute(column2.getName());
+        assertNull(objEntity.getAttribute(oatr1.getName()));
+        assertEquals(0, objEntity.getAttributes().size());
+        assertNull(dbEntity.getAttribute(column2.getName()));
+
+        List<MergerToken> tokens = createMergeTokens();
+        assertEquals(1, tokens.size());
+        MergerToken token = tokens.get(0);
+        if (token.getDirection().isToDb()) {
+            token = token.createReverse(mergerFactory());
+        }
+        assertTrue(token instanceof AddColumnToModel);
+        execute(token);
+        assertEquals(1, objEntity.getAttributes().size());
+        assertEquals("java.lang.String", objEntity.getAttributes().iterator()
+                .next().getType());
+
+        // clear up
+        map.removeObjEntity(objEntity.getName(), true);
+        map.removeDbEntity(dbEntity.getName(), true);
+        resolver.refreshMappingCache();
+        assertNull(map.getObjEntity(objEntity.getName()));
+        assertNull(map.getDbEntity(dbEntity.getName()));
+        assertFalse(map.getDbEntities().contains(dbEntity));
+
+        assertTokensAndExecute(1, 0);
+        assertTokensAndExecute(0, 0);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/merge/AddColumnToModelTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/merge/AddColumnToModelTest.java b/cayenne-server/src/test/java/org/apache/cayenne/merge/AddColumnToModelTest.java
deleted file mode 100644
index c510418..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/merge/AddColumnToModelTest.java
+++ /dev/null
@@ -1,94 +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.merge;
-
-import java.sql.Types;
-import java.util.List;
-
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.ObjAttribute;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class AddColumnToModelTest extends MergeCase {
-
-    public void testAddColumn() throws Exception {
-        dropTableIfPresent("NEW_TABLE");
-        assertTokensAndExecute(0, 0);
-
-        DbEntity dbEntity = new DbEntity("NEW_TABLE");
-
-        DbAttribute column1 = new DbAttribute("ID", Types.INTEGER, dbEntity);
-        column1.setMandatory(true);
-        column1.setPrimaryKey(true);
-        dbEntity.addAttribute(column1);
-
-        DbAttribute column2 = new DbAttribute("NAME", Types.VARCHAR, dbEntity);
-        column2.setMaxLength(10);
-        column2.setMandatory(false);
-        dbEntity.addAttribute(column2);
-
-        map.addDbEntity(dbEntity);
-
-        assertTokensAndExecute(1, 0);
-        assertTokensAndExecute(0, 0);
-
-        ObjEntity objEntity = new ObjEntity("NewTable");
-        objEntity.setDbEntity(dbEntity);
-        ObjAttribute oatr1 = new ObjAttribute("name");
-        oatr1.setDbAttributePath(column2.getName());
-        oatr1.setType("java.lang.String");
-        objEntity.addAttribute(oatr1);
-        map.addObjEntity(objEntity);
-
-        // remove name column
-        objEntity.removeAttribute(oatr1.getName());
-        dbEntity.removeAttribute(column2.getName());
-        assertNull(objEntity.getAttribute(oatr1.getName()));
-        assertEquals(0, objEntity.getAttributes().size());
-        assertNull(dbEntity.getAttribute(column2.getName()));
-
-        List<MergerToken> tokens = createMergeTokens();
-        assertEquals(1, tokens.size());
-        MergerToken token = tokens.get(0);
-        if (token.getDirection().isToDb()) {
-            token = token.createReverse(mergerFactory());
-        }
-        assertTrue(token instanceof AddColumnToModel);
-        execute(token);
-        assertEquals(1, objEntity.getAttributes().size());
-        assertEquals("java.lang.String", objEntity.getAttributes().iterator()
-                .next().getType());
-
-        // clear up
-        map.removeObjEntity(objEntity.getName(), true);
-        map.removeDbEntity(dbEntity.getName(), true);
-        resolver.refreshMappingCache();
-        assertNull(map.getObjEntity(objEntity.getName()));
-        assertNull(map.getDbEntity(dbEntity.getName()));
-        assertFalse(map.getDbEntities().contains(dbEntity));
-
-        assertTokensAndExecute(1, 0);
-        assertTokensAndExecute(0, 0);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/merge/CreateTableToModelIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/merge/CreateTableToModelIT.java b/cayenne-server/src/test/java/org/apache/cayenne/merge/CreateTableToModelIT.java
new file mode 100644
index 0000000..d0012a1
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/merge/CreateTableToModelIT.java
@@ -0,0 +1,97 @@
+/*****************************************************************
+ *   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.merge;
+
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.sql.Types;
+import java.util.List;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class CreateTableToModelIT extends MergeCase {
+
+    public void testAddTable() throws Exception {
+        dropTableIfPresent("NEW_TABLE");
+        assertTokensAndExecute(0, 0);
+
+        DbEntity dbEntity = new DbEntity("NEW_TABLE");
+
+        DbAttribute column1 = new DbAttribute("ID", Types.INTEGER, dbEntity);
+        column1.setMandatory(true);
+        column1.setPrimaryKey(true);
+        dbEntity.addAttribute(column1);
+
+        DbAttribute column2 = new DbAttribute("NAME", Types.VARCHAR, dbEntity);
+        column2.setMaxLength(10);
+        column2.setMandatory(false);
+        dbEntity.addAttribute(column2);
+
+        // for the new entity to the db
+        execute(mergerFactory().createCreateTableToDb(dbEntity));
+
+        List<MergerToken> tokens = createMergeTokens();
+        assertEquals(1, tokens.size());
+        MergerToken token = tokens.get(0);
+        if (token.getDirection().isToDb()) {
+            token = token.createReverse(mergerFactory());
+        }
+        assertTrue(token.getClass().getName(),
+                token instanceof CreateTableToModel);
+
+        execute(token);
+
+        ObjEntity objEntity = null;
+        for (ObjEntity candidate : map.getObjEntities()) {
+            if (dbEntity.getName().equalsIgnoreCase(candidate.getDbEntityName())) {
+                objEntity = candidate;
+                break;
+            }
+        }
+        assertNotNull(objEntity);
+
+        assertEquals(objEntity.getClassName(), map.getDefaultPackage() + "."
+                + objEntity.getName());
+        assertEquals(objEntity.getSuperClassName(), map.getDefaultSuperclass());
+        assertEquals(objEntity.getClientClassName(),
+                map.getDefaultClientPackage() + "." + objEntity.getName());
+        assertEquals(objEntity.getClientSuperClassName(),
+                map.getDefaultClientSuperclass());
+
+        assertEquals(1, objEntity.getAttributes().size());
+        assertEquals("java.lang.String", objEntity.getAttributes().iterator()
+                .next().getType());
+
+        // clear up
+        // fix psql case issue
+        map.removeDbEntity(objEntity.getDbEntity().getName(), true);
+        map.removeObjEntity(objEntity.getName(), true);
+        map.removeDbEntity(dbEntity.getName(), true);
+        resolver.refreshMappingCache();
+        assertNull(map.getObjEntity(objEntity.getName()));
+        assertNull(map.getDbEntity(dbEntity.getName()));
+        assertFalse(map.getDbEntities().contains(dbEntity));
+
+        assertTokensAndExecute(1, 0);
+        assertTokensAndExecute(0, 0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/merge/CreateTableToModelTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/merge/CreateTableToModelTest.java b/cayenne-server/src/test/java/org/apache/cayenne/merge/CreateTableToModelTest.java
deleted file mode 100644
index 3c57f7d..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/merge/CreateTableToModelTest.java
+++ /dev/null
@@ -1,97 +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.merge;
-
-import java.sql.Types;
-import java.util.List;
-
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class CreateTableToModelTest extends MergeCase {
-
-    public void testAddTable() throws Exception {
-        dropTableIfPresent("NEW_TABLE");
-        assertTokensAndExecute(0, 0);
-
-        DbEntity dbEntity = new DbEntity("NEW_TABLE");
-
-        DbAttribute column1 = new DbAttribute("ID", Types.INTEGER, dbEntity);
-        column1.setMandatory(true);
-        column1.setPrimaryKey(true);
-        dbEntity.addAttribute(column1);
-
-        DbAttribute column2 = new DbAttribute("NAME", Types.VARCHAR, dbEntity);
-        column2.setMaxLength(10);
-        column2.setMandatory(false);
-        dbEntity.addAttribute(column2);
-
-        // for the new entity to the db
-        execute(mergerFactory().createCreateTableToDb(dbEntity));
-
-        List<MergerToken> tokens = createMergeTokens();
-        assertEquals(1, tokens.size());
-        MergerToken token = tokens.get(0);
-        if (token.getDirection().isToDb()) {
-            token = token.createReverse(mergerFactory());
-        }
-        assertTrue(token.getClass().getName(),
-                token instanceof CreateTableToModel);
-
-        execute(token);
-
-        ObjEntity objEntity = null;
-        for (ObjEntity candidate : map.getObjEntities()) {
-            if (dbEntity.getName().equalsIgnoreCase(candidate.getDbEntityName())) {
-                objEntity = candidate;
-                break;
-            }
-        }
-        assertNotNull(objEntity);
-
-        assertEquals(objEntity.getClassName(), map.getDefaultPackage() + "."
-                + objEntity.getName());
-        assertEquals(objEntity.getSuperClassName(), map.getDefaultSuperclass());
-        assertEquals(objEntity.getClientClassName(),
-                map.getDefaultClientPackage() + "." + objEntity.getName());
-        assertEquals(objEntity.getClientSuperClassName(),
-                map.getDefaultClientSuperclass());
-
-        assertEquals(1, objEntity.getAttributes().size());
-        assertEquals("java.lang.String", objEntity.getAttributes().iterator()
-                .next().getType());
-
-        // clear up
-        // fix psql case issue
-        map.removeDbEntity(objEntity.getDbEntity().getName(), true);
-        map.removeObjEntity(objEntity.getName(), true);
-        map.removeDbEntity(dbEntity.getName(), true);
-        resolver.refreshMappingCache();
-        assertNull(map.getObjEntity(objEntity.getName()));
-        assertNull(map.getDbEntity(dbEntity.getName()));
-        assertFalse(map.getDbEntities().contains(dbEntity));
-
-        assertTokensAndExecute(1, 0);
-        assertTokensAndExecute(0, 0);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/merge/DropColumnToModelIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/merge/DropColumnToModelIT.java b/cayenne-server/src/test/java/org/apache/cayenne/merge/DropColumnToModelIT.java
new file mode 100644
index 0000000..b11d765
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/merge/DropColumnToModelIT.java
@@ -0,0 +1,226 @@
+/*****************************************************************
+ *   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.merge;
+
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbJoin;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.map.ObjAttribute;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.sql.Types;
+import java.util.List;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class DropColumnToModelIT extends MergeCase {
+
+    public void testSimpleColumn() throws Exception {
+        dropTableIfPresent("NEW_TABLE");
+
+        assertTokensAndExecute(0, 0);
+
+        DbEntity dbEntity = new DbEntity("NEW_TABLE");
+
+        DbAttribute column1 = new DbAttribute("ID", Types.INTEGER, dbEntity);
+        column1.setMandatory(true);
+        column1.setPrimaryKey(true);
+        dbEntity.addAttribute(column1);
+
+        DbAttribute column2 = new DbAttribute("NAME", Types.VARCHAR, dbEntity);
+        column2.setMaxLength(10);
+        column2.setMandatory(false);
+        dbEntity.addAttribute(column2);
+
+        map.addDbEntity(dbEntity);
+
+        assertTokensAndExecute(1, 0);
+        assertTokensAndExecute(0, 0);
+
+        ObjEntity objEntity = new ObjEntity("NewTable");
+        objEntity.setDbEntity(dbEntity);
+        ObjAttribute oatr1 = new ObjAttribute("name");
+        oatr1.setDbAttributePath(column2.getName());
+        oatr1.setType("java.lang.String");
+        objEntity.addAttribute(oatr1);
+        map.addObjEntity(objEntity);
+
+        // force drop name column in db
+        MergerToken token = mergerFactory().createDropColumnToDb(dbEntity, column2);
+        execute(token);
+
+        List<MergerToken> tokens = createMergeTokens();
+        assertEquals(1, tokens.size());
+        token = tokens.get(0);
+        if (token.getDirection().isToDb()) {
+            token = token.createReverse(mergerFactory());
+        }
+        assertTrue(token instanceof DropColumnToModel);
+        execute(token);
+        assertNull(dbEntity.getAttribute(column2.getName()));
+        assertNull(objEntity.getAttribute(oatr1.getName()));
+
+        // clear up
+        map.removeObjEntity(objEntity.getName(), true);
+        map.removeDbEntity(dbEntity.getName(), true);
+        resolver.refreshMappingCache();
+        assertNull(map.getObjEntity(objEntity.getName()));
+        assertNull(map.getDbEntity(dbEntity.getName()));
+        assertFalse(map.getDbEntities().contains(dbEntity));
+
+        assertTokensAndExecute(1, 0);
+        assertTokensAndExecute(0, 0);
+    }
+
+    public void testRemoveFKColumnWithoutRelationshipInDb() throws Exception {
+        dropTableIfPresent("NEW_TABLE");
+        dropTableIfPresent("NEW_TABLE2");
+
+        assertTokensAndExecute(0, 0);
+
+        DbEntity dbEntity1 = new DbEntity("NEW_TABLE");
+
+        DbAttribute e1col1 = new DbAttribute("ID", Types.INTEGER, dbEntity1);
+        e1col1.setMandatory(true);
+        e1col1.setPrimaryKey(true);
+        dbEntity1.addAttribute(e1col1);
+
+        DbAttribute e1col2 = new DbAttribute("NAME", Types.VARCHAR, dbEntity1);
+        e1col2.setMaxLength(10);
+        e1col2.setMandatory(false);
+        dbEntity1.addAttribute(e1col2);
+
+        map.addDbEntity(dbEntity1);
+
+        DbEntity dbEntity2 = new DbEntity("NEW_TABLE2");
+        DbAttribute e2col1 = new DbAttribute("ID", Types.INTEGER, dbEntity2);
+        e2col1.setMandatory(true);
+        e2col1.setPrimaryKey(true);
+        dbEntity2.addAttribute(e2col1);
+        DbAttribute e2col2 = new DbAttribute("FK", Types.INTEGER, dbEntity2);
+        dbEntity2.addAttribute(e2col2);
+        DbAttribute e2col3 = new DbAttribute("NAME", Types.VARCHAR, dbEntity2);
+        e2col3.setMaxLength(10);
+        dbEntity2.addAttribute(e2col3);
+
+        map.addDbEntity(dbEntity2);
+
+        assertTokensAndExecute(2, 0);
+        assertTokensAndExecute(0, 0);
+
+        // force drop fk column in db
+        execute(mergerFactory().createDropColumnToDb(dbEntity2, e2col2));
+
+        // create db relationships, but do not sync them to db
+        DbRelationship rel1To2 = new DbRelationship("rel1To2");
+        rel1To2.setSourceEntity(dbEntity1);
+        rel1To2.setTargetEntity(dbEntity2);
+        rel1To2.setToMany(true);
+        rel1To2.addJoin(new DbJoin(rel1To2, e1col1.getName(), e2col2.getName()));
+        dbEntity1.addRelationship(rel1To2);
+        DbRelationship rel2To1 = new DbRelationship("rel2To1");
+        rel2To1.setSourceEntity(dbEntity2);
+        rel2To1.setTargetEntity(dbEntity1);
+        rel2To1.setToMany(false);
+        rel2To1.addJoin(new DbJoin(rel2To1, e2col2.getName(), e1col1.getName()));
+        dbEntity2.addRelationship(rel2To1);
+        assertSame(rel1To2, rel2To1.getReverseRelationship());
+        assertSame(rel2To1, rel1To2.getReverseRelationship());
+
+        // create ObjEntities
+        ObjEntity objEntity1 = new ObjEntity("NewTable");
+        objEntity1.setDbEntity(dbEntity1);
+        ObjAttribute oatr1 = new ObjAttribute("name");
+        oatr1.setDbAttributePath(e1col2.getName());
+        oatr1.setType("java.lang.String");
+        objEntity1.addAttribute(oatr1);
+        map.addObjEntity(objEntity1);
+        ObjEntity objEntity2 = new ObjEntity("NewTable2");
+        objEntity2.setDbEntity(dbEntity2);
+        ObjAttribute o2a1 = new ObjAttribute("name");
+        o2a1.setDbAttributePath(e2col3.getName());
+        o2a1.setType("java.lang.String");
+        objEntity2.addAttribute(o2a1);
+        map.addObjEntity(objEntity2);
+
+        // create ObjRelationships
+        assertEquals(0, objEntity1.getRelationships().size());
+        assertEquals(0, objEntity2.getRelationships().size());
+        ObjRelationship objRel1To2 = new ObjRelationship("objRel1To2");
+        objRel1To2.addDbRelationship(rel1To2);
+        objRel1To2.setSourceEntity(objEntity1);
+        objRel1To2.setTargetEntity(objEntity2);
+        objEntity1.addRelationship(objRel1To2);
+        ObjRelationship objRel2To1 = new ObjRelationship("objRel2To1");
+        objRel2To1.addDbRelationship(rel2To1);
+        objRel2To1.setSourceEntity(objEntity2);
+        objRel2To1.setTargetEntity(objEntity1);
+        objEntity2.addRelationship(objRel2To1);
+        assertEquals(1, objEntity1.getRelationships().size());
+        assertEquals(1, objEntity2.getRelationships().size());
+        assertSame(objRel1To2, objRel2To1.getReverseRelationship());
+        assertSame(objRel2To1, objRel1To2.getReverseRelationship());
+
+        // try do use the merger to remove the column and relationship in the model
+        List<MergerToken> tokens = createMergeTokens();
+        assertTokens(tokens, 2, 0);
+        // TODO: reversing the following two tokens should also reverse the order
+        MergerToken token0 = tokens.get(0).createReverse(mergerFactory());
+        MergerToken token1 = tokens.get(1).createReverse(mergerFactory());
+        if (!(token0 instanceof DropRelationshipToModel && token1 instanceof DropColumnToModel
+                || token1 instanceof DropRelationshipToModel && token0 instanceof DropColumnToModel)) {
+            fail();
+        }
+        // do not execute DropRelationshipToModel, only DropColumnToModel.
+        if (token1 instanceof DropColumnToModel) {
+            execute(token1);
+        } else {
+            execute(token0);
+        }
+
+        // check after merging
+        assertNull(dbEntity2.getAttribute(e2col2.getName()));
+        assertEquals(0, dbEntity1.getRelationships().size());
+        assertEquals(0, dbEntity2.getRelationships().size());
+        assertEquals(0, objEntity1.getRelationships().size());
+        assertEquals(0, objEntity2.getRelationships().size());
+
+        // clear up
+
+        dbEntity1.removeRelationship(rel1To2.getName());
+        dbEntity2.removeRelationship(rel2To1.getName());
+        map.removeObjEntity(objEntity1.getName(), true);
+        map.removeDbEntity(dbEntity1.getName(), true);
+        map.removeObjEntity(objEntity2.getName(), true);
+        map.removeDbEntity(dbEntity2.getName(), true);
+        resolver.refreshMappingCache();
+        assertNull(map.getObjEntity(objEntity1.getName()));
+        assertNull(map.getDbEntity(dbEntity1.getName()));
+        assertNull(map.getObjEntity(objEntity2.getName()));
+        assertNull(map.getDbEntity(dbEntity2.getName()));
+        assertFalse(map.getDbEntities().contains(dbEntity1));
+        assertFalse(map.getDbEntities().contains(dbEntity2));
+
+        assertTokensAndExecute(2, 0);
+        assertTokensAndExecute(0, 0);
+    }
+}