cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aadamc...@apache.org
Subject [1/3] cayenne git commit: hot fix for many-to-many relationships revers engineering
Date Mon, 19 Jan 2015 14:26:33 GMT
Repository: cayenne
Updated Branches:
  refs/heads/master c8ff4355f -> 3b619d4e0


hot fix for many-to-many relationships revers engineering


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/54997aa6
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/54997aa6
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/54997aa6

Branch: refs/heads/master
Commit: 54997aa6dcad98a3c297faf9eec936c198ef6fa8
Parents: 44642ea
Author: alexkolonitsky <Alex.Kolonitsky@gmail.com>
Authored: Fri Jan 16 14:04:29 2015 +0300
Committer: alexkolonitsky <Alex.Kolonitsky@gmail.com>
Committed: Fri Jan 16 14:04:29 2015 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/access/DbLoader.java     | 87 +++++++++++++-------
 .../loader/ManyToManyCandidateEntity.java       |  2 +-
 .../org/apache/cayenne/map/DbRelationship.java  | 13 +++
 .../org/apache/cayenne/map/Relationship.java    |  7 +-
 .../java/org/apache/cayenne/merge/DbMerger.java |  2 +-
 .../apache/cayenne/util/EntityMergeSupport.java | 52 ++++++++----
 .../org/apache/cayenne/map/DataMapTest.java     |  6 +-
 .../java/org/apache/cayenne/map/DbEntityIT.java |  4 +-
 .../apache/cayenne/map/DbRelationshipIT.java    |  4 +-
 .../apache/cayenne/map/ObjRelationshipIT.java   | 14 ++--
 .../apache/cayenne/map/RelationshipTest.java    |  2 +-
 .../cayenne/merge/DropColumnToModelIT.java      |  8 +-
 .../merge/DropRelationshipToModelIT.java        | 15 ++--
 .../apache/cayenne/merge/MergerFactoryIT.java   | 21 +++--
 .../cayenne/util/EntityMergeSupportIT.java      |  4 +-
 .../cayenne/tools/dbimport/DbImportAction.java  | 46 ++++++-----
 .../tools/dbimport/DbImportConfiguration.java   | 12 ++-
 .../dialog/ResolveDbRelationshipDialog.java     |  2 +-
 .../InferRelationshipsController.java           |  2 +-
 .../dialog/objentity/ObjRelationshipInfo.java   |  4 +-
 .../editor/ObjRelationshipTableModel.java       |  2 +-
 .../dbentity/DbRelationshipTableModel.java      |  2 +-
 .../cayenne/wocompat/EOModelProcessor.java      |  4 +-
 .../dbimport/testUnFlattensManyToMany.map.xml   |  8 +-
 .../testUnFlattensManyToMany.map.xml-result     | 36 +++++++-
 .../tools/dbimport/testUnFlattensManyToMany.sql | 22 +++++
 26 files changed, 256 insertions(+), 125 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java
index 864e4f0..07b674c 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java
@@ -445,7 +445,15 @@ public class DbLoader {
     /**
      * Creates an ObjEntity for each DbEntity in the map.
      */
-    protected Collection<ObjEntity> loadObjEntities(DataMap map, DbLoaderConfiguration config, Collection<DbEntity> entities) {
+    public Collection<ObjEntity> loadObjEntities(DataMap map, DbLoaderConfiguration config, Collection<DbEntity> entities) {
+        Collection<ObjEntity> loadedEntities = DbLoader.loadObjEntities(map, config, entities, nameGenerator);
+
+        createEntityMerger(map).synchronizeWithDbEntities(loadedEntities);
+
+        return loadedEntities;
+    }
+
+    public static Collection<ObjEntity> loadObjEntities(DataMap map, DbLoaderConfiguration config, Collection<DbEntity> entities, ObjectNameGenerator nameGenerator) {
         if (entities.isEmpty()) {
             return Collections.emptyList();
         }
@@ -477,9 +485,6 @@ public class DbLoader {
             loadedEntities.add(objEntity);
         }
 
-        // update ObjEntity attributes and relationships
-        createEntityMerger(map).synchronizeWithDbEntities(loadedEntities);
-
         return loadedEntities;
     }
 
@@ -491,6 +496,10 @@ public class DbLoader {
     }
 
     protected void loadDbRelationships(DbLoaderConfiguration config, Map<DbPath, Map<String, DbEntity>> tables) throws SQLException {
+        if (config.isSkipRelationshipsLoading()) {
+            return;
+        }
+
         // Get all the foreign keys referencing this table
 
         for (Map.Entry<DbPath, Map<String, DbEntity>> pathEntry : tables.entrySet()) {
@@ -518,28 +527,31 @@ public class DbLoader {
                     continue;
                 }
 
+                // forwardRelationship is a reference from table with primary key
                 DbRelationship forwardRelationship = new DbRelationship(generateName(pkEntity, key, true));
                 forwardRelationship.setSourceEntity(pkEntity);
-                forwardRelationship.setTargetEntity(fkEntity);
+                forwardRelationship.setTargetEntityName(fkEntity);
 
+                // forwardRelationship is a reference from table with foreign key, it is what exactly we load from db
                 DbRelationshipDetected reverseRelationship = new DbRelationshipDetected(generateName(fkEntity, key, false));
                 reverseRelationship.setFkName(key.getFKName());
                 reverseRelationship.setSourceEntity(fkEntity);
-                reverseRelationship.setTargetEntity(pkEntity);
+                reverseRelationship.setTargetEntityName(pkEntity);
                 reverseRelationship.setToMany(false);
-                if (delegate.dbRelationshipLoaded(fkEntity, reverseRelationship)) {
-                    fkEntity.addRelationship(reverseRelationship);
-                }
 
-                boolean toPK = createAndAppendJoins(exportedKeys, pkEntity, fkEntity, forwardRelationship, reverseRelationship);
+                createAndAppendJoins(exportedKeys, pkEntity, fkEntity, forwardRelationship, reverseRelationship);
 
-                forwardRelationship.setToDependentPK(toPK);
+                boolean toDependentPK = isToDependentPK(forwardRelationship);
+                forwardRelationship.setToDependentPK(toDependentPK);
 
-                boolean isOneToOne = toPK && fkEntity.getPrimaryKeys().size()
-                        == forwardRelationship.getJoins().size();
+                boolean isOneToOne = toDependentPK && fkEntity.getPrimaryKeys().size() == forwardRelationship.getJoins().size();
 
                 forwardRelationship.setToMany(!isOneToOne);
                 forwardRelationship.setName(generateName(pkEntity, key, !isOneToOne));
+
+                if (delegate.dbRelationshipLoaded(fkEntity, reverseRelationship)) {
+                    fkEntity.addRelationship(reverseRelationship);
+                }
                 if (delegate.dbRelationshipLoaded(pkEntity, forwardRelationship)) {
                     pkEntity.addRelationship(forwardRelationship);
                 }
@@ -547,8 +559,17 @@ public class DbLoader {
         }
     }
 
-    private boolean createAndAppendJoins(Set<ExportedKey> exportedKeys, DbEntity pkEntity, DbEntity fkEntity, DbRelationship forwardRelationship, DbRelationshipDetected reverseRelationship) {
-        boolean toPK = true;
+    private boolean isToDependentPK(DbRelationship forwardRelationship) {
+        for (DbJoin dbJoin : forwardRelationship.getJoins()) {
+            if (!dbJoin.getTarget().isPrimaryKey()) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private void createAndAppendJoins(Set<ExportedKey> exportedKeys, DbEntity pkEntity, DbEntity fkEntity, DbRelationship forwardRelationship, DbRelationshipDetected reverseRelationship) {
         for (ExportedKey exportedKey : exportedKeys) {
             // Create and append joins
             String pkName = exportedKey.getPKColumnName();
@@ -569,12 +590,7 @@ public class DbLoader {
 
             forwardRelationship.addJoin(new DbJoin(forwardRelationship, pkName, fkName));
             reverseRelationship.addJoin(new DbJoin(reverseRelationship, fkName, pkName));
-
-            if (!pkAtt.isPrimaryKey()) {
-                toPK = false;
-            }
         }
-        return toPK;
     }
 
     private Map<String, Set<ExportedKey>> loadExportedKeys(DbLoaderConfiguration config, DbPath dbPath, Map<String, DbEntity> tables) throws SQLException {
@@ -648,14 +664,17 @@ public class DbLoader {
     /**
      * Flattens many-to-many relationships in the generated model.
      */
-    private void flattenManyToManyRelationships(DataMap map, Collection<ObjEntity> loadedObjEntities) {
+    public static void flattenManyToManyRelationships(DataMap map, Collection<ObjEntity> loadedObjEntities, ObjectNameGenerator objectNameGenerator) {
+        if (loadedObjEntities.isEmpty()) {
+            return;
+        }
         Collection<ObjEntity> entitiesForDelete = new LinkedList<ObjEntity>();
 
-        for (ObjEntity curEntity : map.getObjEntities()) {
+        for (ObjEntity curEntity : loadedObjEntities) {
             ManyToManyCandidateEntity entity = ManyToManyCandidateEntity.build(curEntity);
 
             if (entity != null) {
-                entity.optimizeRelationships(getNameGenerator());
+                entity.optimizeRelationships(objectNameGenerator);
                 entitiesForDelete.add(curEntity);
             }
         }
@@ -760,21 +779,24 @@ public class DbLoader {
      * @since 4.0
      */
     public void load(DataMap dataMap, DbLoaderConfiguration config) throws SQLException {
+        LOGGER.info("Schema loading...");
 
         Map<DbPath, Map<String, DbEntity>> tables = getTables(config, config.getTableTypes());
         List<DbEntity> entities = loadDbEntities(dataMap, config, tables);
 
         if (entities != null) {
-            if (!config.isSkipRelationshipsLoading()) {
-                loadDbRelationships(config, tables);
-            }
+            loadDbRelationships(config, tables);
 
-            Collection<ObjEntity> loadedObjEntities = loadObjEntities(dataMap, config, entities);
-            flattenManyToManyRelationships(dataMap, loadedObjEntities);
-            fireObjEntitiesAddedEvents(loadedObjEntities);
+            prepareObjLayer(dataMap, config, entities);
         }
     }
 
+    public void prepareObjLayer(DataMap dataMap, DbLoaderConfiguration config, Collection<DbEntity> entities) {
+        Collection<ObjEntity> loadedObjEntities = loadObjEntities(dataMap, config, entities);
+        flattenManyToManyRelationships(dataMap, loadedObjEntities, getNameGenerator());
+        fireObjEntitiesAddedEvents(loadedObjEntities);
+    }
+
     /**
      * Performs database reverse engineering to match the specified catalog,
      * schema, table name and table type patterns and fills the specified
@@ -982,10 +1004,11 @@ public class DbLoader {
      */
     public void setNameGenerator(ObjectNameGenerator strategy) {
         if (strategy == null) {
-            throw new NullPointerException("Null strategy not allowed");
+            LOGGER.warn("Attempt to set null into NameGenerator. LegacyNameGenerator will be used.");
+            this.nameGenerator = new LegacyNameGenerator();
+        } else {
+            this.nameGenerator = strategy;
         }
-
-        this.nameGenerator = strategy;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/cayenne-server/src/main/java/org/apache/cayenne/access/loader/ManyToManyCandidateEntity.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/loader/ManyToManyCandidateEntity.java b/cayenne-server/src/main/java/org/apache/cayenne/access/loader/ManyToManyCandidateEntity.java
index ef8391d..e51d936 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/loader/ManyToManyCandidateEntity.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/loader/ManyToManyCandidateEntity.java
@@ -117,7 +117,7 @@ public class ManyToManyCandidateEntity {
                 nameGenerator.createDbRelationshipName(key, true)));
 
         newRelationship.setSourceEntity(srcEntity);
-        newRelationship.setTargetEntity(dstEntity);
+        newRelationship.setTargetEntityName(dstEntity);
 
         newRelationship.addDbRelationship(rel1);
         newRelationship.addDbRelationship(rel2);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java b/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
index 5234ff4..cee22e8 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
@@ -535,4 +535,17 @@ public class DbRelationship extends Relationship implements ConfigurationNode {
                     && Util.nullSafeEquals(j.targetName, this.targetName);
         }
     }
+
+    public String toString() {
+        StringBuilder res = new StringBuilder("Db Relationship : ");
+        res.append(toMany ? "toMany" : "toOne ");
+
+        String sourceEntityName = getSourceEntity().getName();
+        for (DbJoin join : joins) {
+            res.append(" (").append(sourceEntityName).append(".").append(join.getSourceName()).append(", ")
+                    .append(targetEntityName).append(".").append(join.getTargetName()).append(")");
+        }
+        return res.toString();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/cayenne-server/src/main/java/org/apache/cayenne/map/Relationship.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/Relationship.java b/cayenne-server/src/main/java/org/apache/cayenne/map/Relationship.java
index 1c34172..3aadbfc 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/Relationship.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/Relationship.java
@@ -91,12 +91,11 @@ public abstract class Relationship implements CayenneMapEntry, XMLSerializable,
     /**
      * Sets relationship target entity. Internally calls <code>setTargetEntityName</code>.
      */
-    public void setTargetEntity(Entity targetEntity) {
+    public void setTargetEntityName(Entity targetEntity) {
         if (targetEntity != null) {
             setTargetEntityName(targetEntity.getName());
-        }
-        else {
-            setTargetEntityName(null);
+        } else {
+            setTargetEntityName((String) null);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/cayenne-server/src/main/java/org/apache/cayenne/merge/DbMerger.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/merge/DbMerger.java b/cayenne-server/src/main/java/org/apache/cayenne/merge/DbMerger.java
index e537b8a..c5b9547 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/merge/DbMerger.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/merge/DbMerger.java
@@ -251,7 +251,7 @@ public class DbMerger {
                 }
 
                 detected.setSourceEntity(dbEntity);
-                detected.setTargetEntity(targetEntity);
+                detected.setTargetEntityName(targetEntity);
 
                 // manipulate the joins to match the DbAttributes in the model
                 for (DbJoin join : detected.getJoins()) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/cayenne-server/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java b/cayenne-server/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java
index 9772794..9b26239 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java
@@ -40,12 +40,16 @@ import org.apache.cayenne.map.naming.LegacyNameGenerator;
 import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator;
 import org.apache.cayenne.map.naming.NameCheckers;
 import org.apache.cayenne.map.naming.ObjectNameGenerator;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 /**
  * Implements methods for entity merging.
  */
 public class EntityMergeSupport {
 
+    private static final Log LOG = LogFactory.getLog(EntityMergeSupport.class);
+
     private static final Map<String, String> CLASS_TO_PRIMITIVE;
 
     static {
@@ -162,27 +166,43 @@ public class EntityMergeSupport {
     }
 
     private boolean addMissingRelationships(ObjEntity entity) {
-        boolean changed = false;
-        for (DbRelationship dr : getRelationshipsToAdd(entity)) {
-            DbEntity targetEntity = dr.getTargetEntity();
-
-            for (Entity mappedTarget : map.getMappedEntities(targetEntity)) {
+        List<DbRelationship> relationshipsToAdd = getRelationshipsToAdd(entity);
+        if (relationshipsToAdd.isEmpty()) {
+            return false;
+        }
 
-                // avoid duplicate names
-                String relationshipName = nameGenerator.createObjRelationshipName(dr);
-                relationshipName = DefaultUniqueNameGenerator.generate(NameCheckers.objRelationship, entity, relationshipName);
+        for (DbRelationship dr : relationshipsToAdd) {
+            DbEntity targetEntity = dr.getTargetEntity();
 
-                ObjRelationship or = new ObjRelationship(relationshipName);
-                or.addDbRelationship(dr);
-                or.setSourceEntity(entity);
-                or.setTargetEntity(mappedTarget);
-                entity.addRelationship(or);
+            Collection<ObjEntity> mappedObjEntities = map.getMappedEntities(targetEntity);
+            if (!mappedObjEntities.isEmpty()) {
+                for (Entity mappedTarget : mappedObjEntities) {
+                    createObjRelationship(entity, dr, mappedTarget.getName());
+                }
+            } else {
+                LOG.warn("Can't find ObjEntity for " + dr.getTargetEntityName());
+                LOG.warn("Db Relationship (" + dr + ") will have GUESSED Obj Relationship reflection. ");
 
-                fireRelationshipAdded(or);
-                changed = true;
+                if (targetEntity == null) {
+                    targetEntity = new DbEntity(dr.getTargetEntityName());
+                }
+                createObjRelationship(entity, dr, nameGenerator.createObjEntityName(targetEntity));
             }
         }
-        return changed;
+        return true;
+    }
+
+    private void createObjRelationship(ObjEntity entity, DbRelationship dr, String targetEntityName) {
+        String relationshipName = nameGenerator.createObjRelationshipName(dr);
+        relationshipName = DefaultUniqueNameGenerator.generate(NameCheckers.objRelationship, entity, relationshipName);
+
+        ObjRelationship or = new ObjRelationship(relationshipName);
+        or.addDbRelationship(dr);
+        or.setSourceEntity(entity);
+        or.setTargetEntityName(targetEntityName);
+        entity.addRelationship(or);
+
+        fireRelationshipAdded(or);
     }
 
     private boolean addMissingAttributes(ObjEntity entity) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/cayenne-server/src/test/java/org/apache/cayenne/map/DataMapTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/map/DataMapTest.java b/cayenne-server/src/test/java/org/apache/cayenne/map/DataMapTest.java
index a64b830..d663c70 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/map/DataMapTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/map/DataMapTest.java
@@ -350,15 +350,15 @@ public class DataMapTest {
 
         DbRelationship r1 = new DbRelationship();
         r1.setName("r1");
-        r1.setTargetEntity(e2);
+        r1.setTargetEntityName(e2);
 
         DbRelationship r2 = new DbRelationship();
         r2.setName("r2");
-        r2.setTargetEntity(e1);
+        r2.setTargetEntityName(e1);
 
         DbRelationship r3 = new DbRelationship();
         r3.setName("r3");
-        r3.setTargetEntity(e2);
+        r3.setTargetEntityName(e2);
 
         e1.addRelationship(r1);
         e1.addRelationship(r2);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/cayenne-server/src/test/java/org/apache/cayenne/map/DbEntityIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/map/DbEntityIT.java b/cayenne-server/src/test/java/org/apache/cayenne/map/DbEntityIT.java
index ab63608..41b7c03 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/map/DbEntityIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/map/DbEntityIT.java
@@ -207,12 +207,12 @@ public class DbEntityIT extends ServerCase {
 
         DbRelationship rel = new DbRelationship("relfrom");
         ent.addRelationship(rel);
-        rel.setTargetEntity(otherEntity);
+        rel.setTargetEntityName(otherEntity);
         rel.addJoin(new DbJoin(rel, "a1", "a11"));
 
         DbRelationship rel1 = new DbRelationship("relto");
         otherEntity.addRelationship(rel1);
-        rel1.setTargetEntity(ent);
+        rel1.setTargetEntityName(ent);
         rel1.addJoin(new DbJoin(rel1, "a11", "a1"));
 
         // check that the test case is working

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/cayenne-server/src/test/java/org/apache/cayenne/map/DbRelationshipIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/map/DbRelationshipIT.java b/cayenne-server/src/test/java/org/apache/cayenne/map/DbRelationshipIT.java
index c8d442a..4526fb9 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/map/DbRelationshipIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/map/DbRelationshipIT.java
@@ -93,7 +93,7 @@ public class DbRelationshipIT extends ServerCase {
         DbRelationship rforward = new DbRelationship("rforward");
         e.addRelationship(rforward);
         rforward.setSourceEntity(e);
-        rforward.setTargetEntity(e);
+        rforward.setTargetEntityName(e);
 
         assertNull(rforward.getReverseRelationship());
 
@@ -109,7 +109,7 @@ public class DbRelationshipIT extends ServerCase {
         DbRelationship rback = new DbRelationship("rback");
         e.addRelationship(rback);
         rback.setSourceEntity(e);
-        rback.setTargetEntity(e);
+        rback.setTargetEntityName(e);
 
         assertNull(rforward.getReverseRelationship());
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/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
index bf9f9e1..34da87d 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/map/ObjRelationshipIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/map/ObjRelationshipIT.java
@@ -391,11 +391,11 @@ public class ObjRelationshipIT extends ServerCase {
         DbRelationship r2 = new DbRelationship("Y");
 
         r1.setSourceEntity(artistDBEntity);
-        r1.setTargetEntity(artistExhibitDBEntity);
+        r1.setTargetEntityName(artistExhibitDBEntity);
         r1.setToMany(true);
 
         r2.setSourceEntity(artistExhibitDBEntity);
-        r2.setTargetEntity(exhibitDBEntity);
+        r2.setTargetEntityName(exhibitDBEntity);
         r2.setToMany(false);
 
         ObjRelationship relationship = new ObjRelationship();
@@ -444,13 +444,13 @@ public class ObjRelationshipIT extends ServerCase {
         DbRelationship r3 = new DbRelationship("Z");
 
         r1.setSourceEntity(artistDBEntity);
-        r1.setTargetEntity(artistExhibitDBEntity);
+        r1.setTargetEntityName(artistExhibitDBEntity);
         r1.setToMany(true);
         r2.setSourceEntity(artistExhibitDBEntity);
-        r2.setTargetEntity(exhibitDBEntity);
+        r2.setTargetEntityName(exhibitDBEntity);
         r2.setToMany(false);
         r3.setSourceEntity(exhibitDBEntity);
-        r3.setTargetEntity(galleryDBEntity);
+        r3.setTargetEntityName(galleryDBEntity);
         r3.setToMany(false);
 
         ObjRelationship relationship = new ObjRelationship();
@@ -473,10 +473,10 @@ public class ObjRelationshipIT extends ServerCase {
         DbRelationship r2 = new DbRelationship("Y");
 
         r1.setSourceEntity(artistDBEntity);
-        r1.setTargetEntity(paintingDbEntity);
+        r1.setTargetEntityName(paintingDbEntity);
         r1.setToMany(true);
         r2.setSourceEntity(paintingDbEntity);
-        r2.setTargetEntity(galleryDBEntity);
+        r2.setTargetEntityName(galleryDBEntity);
         r2.setToMany(false);
 
         ObjRelationship relationship = new ObjRelationship();

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/cayenne-server/src/test/java/org/apache/cayenne/map/RelationshipTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/map/RelationshipTest.java b/cayenne-server/src/test/java/org/apache/cayenne/map/RelationshipTest.java
index e6c75ba..265bcac 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/map/RelationshipTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/map/RelationshipTest.java
@@ -48,7 +48,7 @@ public class RelationshipTest {
         Relationship rel = new MockRelationship();
         Entity tstEntity = new MockEntity();
         tstEntity.setName("abc");
-        rel.setTargetEntity(tstEntity);
+        rel.setTargetEntityName(tstEntity);
         assertSame("abc", rel.getTargetEntityName());
     }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/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
index 9bfee73..9005e79 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/merge/DropColumnToModelIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/merge/DropColumnToModelIT.java
@@ -140,13 +140,13 @@ public class DropColumnToModelIT extends MergeCase {
 		// create db relationships, but do not sync them to db
 		DbRelationship rel1To2 = new DbRelationship("rel1To2");
 		rel1To2.setSourceEntity(dbEntity1);
-		rel1To2.setTargetEntity(dbEntity2);
+		rel1To2.setTargetEntityName(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.setTargetEntityName(dbEntity1);
 		rel2To1.setToMany(false);
 		rel2To1.addJoin(new DbJoin(rel2To1, e2col2.getName(), e1col1.getName()));
 		dbEntity2.addRelationship(rel2To1);
@@ -175,12 +175,12 @@ public class DropColumnToModelIT extends MergeCase {
 		ObjRelationship objRel1To2 = new ObjRelationship("objRel1To2");
 		objRel1To2.addDbRelationship(rel1To2);
 		objRel1To2.setSourceEntity(objEntity1);
-		objRel1To2.setTargetEntity(objEntity2);
+		objRel1To2.setTargetEntityName(objEntity2);
 		objEntity1.addRelationship(objRel1To2);
 		ObjRelationship objRel2To1 = new ObjRelationship("objRel2To1");
 		objRel2To1.addDbRelationship(rel2To1);
 		objRel2To1.setSourceEntity(objEntity2);
-		objRel2To1.setTargetEntity(objEntity1);
+		objRel2To1.setTargetEntityName(objEntity1);
 		objEntity2.addRelationship(objRel2To1);
 		assertEquals(1, objEntity1.getRelationships().size());
 		assertEquals(1, objEntity2.getRelationships().size());

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/cayenne-server/src/test/java/org/apache/cayenne/merge/DropRelationshipToModelIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/merge/DropRelationshipToModelIT.java b/cayenne-server/src/test/java/org/apache/cayenne/merge/DropRelationshipToModelIT.java
index e235109..4610fcd 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/merge/DropRelationshipToModelIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/merge/DropRelationshipToModelIT.java
@@ -75,13 +75,13 @@ public class DropRelationshipToModelIT extends MergeCase {
 		// create db relationships
 		DbRelationship rel1To2 = new DbRelationship("rel1To2");
 		rel1To2.setSourceEntity(dbEntity1);
-		rel1To2.setTargetEntity(dbEntity2);
+		rel1To2.setTargetEntityName(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.setTargetEntityName(dbEntity1);
 		rel2To1.setToMany(false);
 		rel2To1.addJoin(new DbJoin(rel2To1, e2col2.getName(), e1col1.getName()));
 		dbEntity2.addRelationship(rel2To1);
@@ -113,12 +113,12 @@ public class DropRelationshipToModelIT extends MergeCase {
 		ObjRelationship objRel1To2 = new ObjRelationship("objRel1To2");
 		objRel1To2.addDbRelationship(rel1To2);
 		objRel1To2.setSourceEntity(objEntity1);
-		objRel1To2.setTargetEntity(objEntity2);
+		objRel1To2.setTargetEntityName(objEntity2);
 		objEntity1.addRelationship(objRel1To2);
 		ObjRelationship objRel2To1 = new ObjRelationship("objRel2To1");
 		objRel2To1.addDbRelationship(rel2To1);
 		objRel2To1.setSourceEntity(objEntity2);
-		objRel2To1.setTargetEntity(objEntity1);
+		objRel2To1.setTargetEntityName(objEntity1);
 		objEntity2.addRelationship(objRel2To1);
 		assertEquals(1, objEntity1.getRelationships().size());
 		assertEquals(1, objEntity2.getRelationships().size());
@@ -130,7 +130,12 @@ public class DropRelationshipToModelIT extends MergeCase {
         dbEntity1.removeRelationship(rel1To2.getName());
         dbEntity2.removeAttribute(e2col2.getName());
         List<MergerToken> tokens = createMergeTokens();
-        assertTokens(tokens, 3, 0);
+        /**
+         * Add Relationship NEW_TABLE->NEW_TABLE2 To Model
+         * Drop Relationship NEW_TABLE2->NEW_TABLE To DB
+         * Drop Column NEW_TABLE2.FK To DB
+         * */
+        assertTokens(tokens, 2, 1);
         for (MergerToken token : tokens) {
             if (token.getDirection().isToDb()) {
                 execute(token);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/cayenne-server/src/test/java/org/apache/cayenne/merge/MergerFactoryIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/merge/MergerFactoryIT.java b/cayenne-server/src/test/java/org/apache/cayenne/merge/MergerFactoryIT.java
index 409f1c9..5c4c51b 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/merge/MergerFactoryIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/merge/MergerFactoryIT.java
@@ -199,7 +199,7 @@ public class MergerFactoryIT extends MergeCase {
         // relation from new_table to artist
         DbRelationship r1 = new DbRelationship("toArtistR1");
         r1.setSourceEntity(dbEntity);
-        r1.setTargetEntity(artistDbEntity);
+        r1.setTargetEntityName(artistDbEntity);
         r1.setToMany(false);
         r1.addJoin(new DbJoin(r1, "ARTIST_ID", "ARTIST_ID"));
         dbEntity.addRelationship(r1);
@@ -207,7 +207,7 @@ public class MergerFactoryIT extends MergeCase {
         // relation from artist to new_table
         DbRelationship r2 = new DbRelationship("toNewTableR2");
         r2.setSourceEntity(artistDbEntity);
-        r2.setTargetEntity(dbEntity);
+        r2.setTargetEntityName(dbEntity);
         r2.setToMany(true);
         r2.addJoin(new DbJoin(r2, "ARTIST_ID", "ARTIST_ID"));
         artistDbEntity.addRelationship(r2);
@@ -219,8 +219,11 @@ public class MergerFactoryIT extends MergeCase {
         dbEntity.removeRelationship(r1.getName());
         artistDbEntity.removeRelationship(r2.getName());
         resolver.refreshMappingCache();
-        assertTokensAndExecute(2, 0);
-//        assertTokensAndExecute(1, 1);
+        /*
+         * Db -Rel 'toArtistR1' - NEW_TABLE 1 -> 1 ARTIST"
+r2 =     * Db -Rel 'toNewTableR2' - ARTIST 1 -> * NEW_TABLE"
+         * */
+        assertTokensAndExecute(1, 1);
         assertTokensAndExecute(0, 0);
 
         // clear up
@@ -257,7 +260,7 @@ public class MergerFactoryIT extends MergeCase {
         // relation from new_table to artist
         DbRelationship r1 = new DbRelationship("toArtistR1");
         r1.setSourceEntity(dbEntity);
-        r1.setTargetEntity(artistDbEntity);
+        r1.setTargetEntityName(artistDbEntity);
         r1.setToMany(false);
         r1.addJoin(new DbJoin(r1, "ARTIST_ID", "ARTIST_ID"));
         dbEntity.addRelationship(r1);
@@ -265,7 +268,7 @@ public class MergerFactoryIT extends MergeCase {
         // relation from artist to new_table
         DbRelationship r2 = new DbRelationship("toNewTableR2");
         r2.setSourceEntity(artistDbEntity);
-        r2.setTargetEntity(dbEntity);
+        r2.setTargetEntityName(dbEntity);
         r2.setToMany(true);
         r2.addJoin(new DbJoin(r2, "ARTIST_ID", "ARTIST_ID"));
         artistDbEntity.addRelationship(r2);
@@ -277,7 +280,11 @@ public class MergerFactoryIT extends MergeCase {
         dbEntity.removeRelationship(r1.getName());
         artistDbEntity.removeRelationship(r2.getName());
         resolver.refreshMappingCache();
-        assertTokensAndExecute(2, 0);
+        /*
+        * Add Relationship ARTIST->NEW_TABLE To Model
+        * Drop Relationship NEW_TABLE->ARTIST To DB
+        * */
+        assertTokensAndExecute(1, 1);
         assertTokensAndExecute(0, 0);
 
         // clear up

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/cayenne-server/src/test/java/org/apache/cayenne/util/EntityMergeSupportIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/util/EntityMergeSupportIT.java b/cayenne-server/src/test/java/org/apache/cayenne/util/EntityMergeSupportIT.java
index 384ddd4..e3f1bc3 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/util/EntityMergeSupportIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/util/EntityMergeSupportIT.java
@@ -66,13 +66,13 @@ public class EntityMergeSupportIT extends MergeCase {
 		// create db relationships
 		DbRelationship rel1To2 = new DbRelationship("rel1To2");
 		rel1To2.setSourceEntity(dbEntity1);
-		rel1To2.setTargetEntity(dbEntity2);
+		rel1To2.setTargetEntityName(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.setTargetEntityName(dbEntity1);
 		rel2To1.setToMany(false);
 		rel2To1.addJoin(new DbJoin(rel2To1, e2col2.getName(), e1col1.getName()));
 		dbEntity2.addRelationship(rel2To1);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportAction.java
----------------------------------------------------------------------
diff --git a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportAction.java b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportAction.java
index bf981ee..cc05e15 100644
--- a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportAction.java
+++ b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportAction.java
@@ -1,21 +1,3 @@
-/*
- * 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.tools.dbimport;
 
 import org.apache.cayenne.access.DbLoader;
@@ -26,9 +8,13 @@ import org.apache.cayenne.configuration.server.DbAdapterFactory;
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.EntityResolver;
 import org.apache.cayenne.map.MapLoader;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.naming.ObjectNameGenerator;
 import org.apache.cayenne.merge.DbMerger;
+import org.apache.cayenne.merge.DropTableToDb;
 import org.apache.cayenne.merge.ExecutingMergerContext;
 import org.apache.cayenne.merge.MergerContext;
 import org.apache.cayenne.merge.MergerFactory;
@@ -37,6 +23,7 @@ import org.apache.cayenne.merge.ModelMergeDelegate;
 import org.apache.cayenne.project.Project;
 import org.apache.cayenne.project.ProjectSaver;
 import org.apache.cayenne.resource.URLResource;
+import org.apache.cayenne.util.EntityMergeSupport;
 import org.apache.cayenne.validation.SimpleValidationFailure;
 import org.apache.cayenne.validation.ValidationFailure;
 import org.apache.cayenne.validation.ValidationResult;
@@ -48,6 +35,7 @@ import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.sql.Connection;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
@@ -117,7 +105,23 @@ public class DbImportAction {
             if (!isBlank(config.getDefaultPackage())) {
                 existing.setDefaultPackage(config.getDefaultPackage());
             }
-            saveLoaded(execute(config.createMergeDelegate(), existing, log(reverse(mergerFactory, mergeTokens))));
+
+
+
+            DataMap executed = execute(config.createMergeDelegate(), existing, log(reverse(mergerFactory, mergeTokens)));
+
+            // TODO DbLoader shouldn't do by it self it should separate processor
+            ObjectNameGenerator nameGenerator = config.getNameGenerator();
+            Collection<ObjEntity> loadedObjEntities = new LinkedList<ObjEntity>();
+            for (MergerToken mergeToken : mergeTokens) {
+                if (mergeToken instanceof DropTableToDb) {
+                    loadedObjEntities.addAll(executed.getMappedEntities(((DropTableToDb) mergeToken).getEntity()));
+                }
+            }
+
+            DbLoader.flattenManyToManyRelationships(executed, loadedObjEntities, nameGenerator);
+
+            saveLoaded(executed);
         }
     }
 
@@ -184,6 +188,10 @@ public class DbImportAction {
         return dataMap;
     }
 
+    private DbLoader getLoader(DbImportConfiguration config, DbAdapter adapter, Connection connection) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+        return config.createLoader(adapter, connection, config.createLoaderDelegate());
+    }
+
     void saveLoaded(DataMap dataMap) throws FileNotFoundException {
         ConfigurationTree<DataMap> projectRoot = new ConfigurationTree<DataMap>(dataMap);
         Project project = new Project(projectRoot);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportConfiguration.java
----------------------------------------------------------------------
diff --git a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportConfiguration.java b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportConfiguration.java
index 7d71aaa..594e99a 100644
--- a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportConfiguration.java
+++ b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportConfiguration.java
@@ -33,6 +33,7 @@ import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.map.naming.LegacyNameGenerator;
 import org.apache.cayenne.map.naming.ObjectNameGenerator;
 import org.apache.cayenne.merge.DbMergerConfig;
 import org.apache.cayenne.merge.DefaultModelMergeDelegate;
@@ -187,13 +188,18 @@ public class DbImportConfiguration {
         };
 
         // TODO: load via DI AdhocObjectFactory
+        loader.setNameGenerator(getNameGenerator());
+
+        return loader;
+    }
+
+    public ObjectNameGenerator getNameGenerator() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
         String namingStrategy = getNamingStrategy();
         if (namingStrategy != null) {
-            ObjectNameGenerator nameGeneratorInst = (ObjectNameGenerator) Class.forName(namingStrategy).newInstance();
-            loader.setNameGenerator(nameGeneratorInst);
+            return (ObjectNameGenerator) Class.forName(namingStrategy).newInstance();
         }
 
-        return loader;
+        return new LegacyNameGenerator(); // TODO
     }
 
     public void setDriver(String jdbcDriver) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java
index 19a51da..ce79cd5 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java
@@ -349,7 +349,7 @@ public class ResolveDbRelationshipDialog extends CayenneDialog {
             if (reverseRelationship == null) {
                 reverseRelationship = new DbRelationship(targetEntityName);
                 reverseRelationship.setSourceEntity(relationship.getTargetEntity());
-                reverseRelationship.setTargetEntity(relationship.getSourceEntity());
+                reverseRelationship.setTargetEntityName(relationship.getSourceEntity());
                 reverseRelationship.setToMany(!relationship.isToMany());
                 relationship.getTargetEntity().addRelationship(reverseRelationship);
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java
index c9093ff..0c6c237 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java
@@ -191,7 +191,7 @@ public class InferRelationshipsController extends InferRelationshipsControllerBa
             mediator.fireDbRelationshipEvent(e);
 
             rel.setSourceEntity(temp.getSource());
-            rel.setTargetEntity(temp.getTarget());
+            rel.setTargetEntityName(temp.getTarget());
             DbJoin join = new DbJoin(rel, temp.getJoinSource().getName(), temp
                     .getJoinTarget()
                     .getName());

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfo.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfo.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfo.java
index 14cbe94..caf6ed5 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfo.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfo.java
@@ -352,7 +352,7 @@ public class ObjRelationshipInfo extends CayenneController implements TreeSelect
 
         // note: NamedObjectFactory doesn't set source or target, just the name
         dbRelationship.setSourceEntity(targetModel.getSource());
-        dbRelationship.setTargetEntity(targetModel.getTarget());
+        dbRelationship.setTargetEntityName(targetModel.getTarget());
         dbRelationship.setToMany(targetModel.isToMany());
         targetModel.getSource().addRelationship(dbRelationship);
 
@@ -606,7 +606,7 @@ public class ObjRelationshipInfo extends CayenneController implements TreeSelect
             // note on events notification - this needs to be propagated
             // via old modeler events, but we leave this to the controller
             // since model knows nothing about Modeler mediator.
-            relationship.setTargetEntity(objectTarget);
+            relationship.setTargetEntityName(objectTarget);
         }
 
         // check for path modifications

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjRelationshipTableModel.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjRelationshipTableModel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjRelationshipTableModel.java
index 8c10a5d..5dca446 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjRelationshipTableModel.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjRelationshipTableModel.java
@@ -169,7 +169,7 @@ public class ObjRelationshipTableModel extends CayenneTableModel {
         }
         else if (column == REL_TARGET) {
             ObjEntity target = (ObjEntity) value;
-            relationship.setTargetEntity(target);
+            relationship.setTargetEntityName(target);
             
             /**
              * Clear existing relationships, otherwise addDbRelationship() might fail

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbRelationshipTableModel.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbRelationshipTableModel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbRelationshipTableModel.java
index e30a38b..50362c3 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbRelationshipTableModel.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbRelationshipTableModel.java
@@ -136,7 +136,7 @@ public class DbRelationshipTableModel extends CayenneTableModel {
 
             // clear joins...
             rel.removeAllJoins();
-            rel.setTargetEntity(target);
+            rel.setTargetEntityName(target);
 
             RelationshipEvent e = new RelationshipEvent(eventSource, rel, entity);
             mediator.fireDbRelationshipEvent(e);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
index a09f0a6..95f6d8e 100644
--- a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
+++ b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
@@ -568,7 +568,7 @@ public class EOModelProcessor {
 
                     dbRel = new DbRelationship();
                     dbRel.setSourceEntity(dbSrc);
-                    dbRel.setTargetEntity(dbTarget);
+                    dbRel.setTargetEntityName(dbTarget);
                     dbRel.setToMany(toMany);
                     dbRel.setName(relName);
                     dbRel.setToDependentPK(toDependentPK);
@@ -599,7 +599,7 @@ public class EOModelProcessor {
                 ObjRelationship rel = new ObjRelationship();
                 rel.setName(relName);
                 rel.setSourceEntity(objEntity);
-                rel.setTargetEntity(target);
+                rel.setTargetEntityName(target);
                 objEntity.addRelationship(rel);
 
                 if (dbRel != null) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testUnFlattensManyToMany.map.xml
----------------------------------------------------------------------
diff --git a/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testUnFlattensManyToMany.map.xml b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testUnFlattensManyToMany.map.xml
index a18b3f3..d3a85be 100644
--- a/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testUnFlattensManyToMany.map.xml
+++ b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testUnFlattensManyToMany.map.xml
@@ -26,8 +26,8 @@
         <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
     </db-entity>
     <db-entity name="A_B" schema="APP">
-        <db-attribute name="A_ID" type="INTEGER" isMandatory="true" length="10"/>
-        <db-attribute name="B_ID" type="INTEGER" isMandatory="true" length="10"/>
+        <db-attribute name="A_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
+        <db-attribute name="B_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
     </db-entity>
     <db-entity name="B" schema="APP">
         <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
@@ -38,7 +38,7 @@
     </obj-entity>
     <obj-entity name="B" className="B" dbEntityName="B">
     </obj-entity>
-    <db-relationship name="aBArray" source="A" target="A_B" toMany="true">
+    <db-relationship name="aBArray" source="A" target="A_B" toDependentPK="true" toMany="true">
         <db-attribute-pair source="ID" target="A_ID"/>
     </db-relationship>
     <db-relationship name="toA" source="A_B" target="A" toMany="false">
@@ -47,7 +47,7 @@
     <db-relationship name="toB" source="A_B" target="B" toMany="false">
         <db-attribute-pair source="B_ID" target="ID"/>
     </db-relationship>
-    <db-relationship name="aBArray" source="B" target="A_B" toMany="true">
+    <db-relationship name="aBArray" source="B" target="A_B" toDependentPK="true" toMany="true">
         <db-attribute-pair source="ID" target="B_ID"/>
     </db-relationship>
     <obj-relationship name="toA" source="AB" target="A" deleteRule="Nullify" db-relationship-path="toA"/>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testUnFlattensManyToMany.map.xml-result
----------------------------------------------------------------------
diff --git a/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testUnFlattensManyToMany.map.xml-result b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testUnFlattensManyToMany.map.xml-result
index f39e30f..f7d6f81 100644
--- a/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testUnFlattensManyToMany.map.xml-result
+++ b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testUnFlattensManyToMany.map.xml-result
@@ -26,8 +26,8 @@
         <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
     </db-entity>
     <db-entity name="A_B" schema="APP">
-        <db-attribute name="A_ID" type="INTEGER" isMandatory="true" length="10"/>
-        <db-attribute name="B_ID" type="INTEGER" isMandatory="true" length="10"/>
+        <db-attribute name="A_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
+        <db-attribute name="B_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
     </db-entity>
     <db-entity name="B" schema="APP">
         <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
@@ -35,6 +35,16 @@
     <db-entity name="C" schema="APP">
         <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
     </db-entity>
+    <db-entity name="X" schema="APP">
+        <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
+    </db-entity>
+    <db-entity name="X_Y" schema="APP">
+        <db-attribute name="X_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
+        <db-attribute name="Y_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
+    </db-entity>
+    <db-entity name="Y" schema="APP">
+        <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
+    </db-entity>
     <obj-entity name="A" className="A" dbEntityName="A">
     </obj-entity>
     <obj-entity name="AB" className="AB" dbEntityName="A_B">
@@ -43,7 +53,11 @@
     </obj-entity>
     <obj-entity name="C" className="org.not.my.home.C" dbEntityName="C">
     </obj-entity>
-    <db-relationship name="aBArray" source="A" target="A_B" toMany="true">
+    <obj-entity name="X" className="org.not.my.home.X" dbEntityName="X">
+    </obj-entity>
+    <obj-entity name="Y" className="org.not.my.home.Y" dbEntityName="Y">
+    </obj-entity>
+    <db-relationship name="aBArray" source="A" target="A_B" toDependentPK="true" toMany="true">
         <db-attribute-pair source="ID" target="A_ID"/>
     </db-relationship>
     <db-relationship name="toA" source="A_B" target="A" toMany="false">
@@ -52,9 +66,23 @@
     <db-relationship name="toB" source="A_B" target="B" toMany="false">
         <db-attribute-pair source="B_ID" target="ID"/>
     </db-relationship>
-    <db-relationship name="aBArray" source="B" target="A_B" toMany="true">
+    <db-relationship name="aBArray" source="B" target="A_B" toDependentPK="true" toMany="true">
         <db-attribute-pair source="ID" target="B_ID"/>
     </db-relationship>
+    <db-relationship name="xYArray" source="X" target="X_Y" toDependentPK="true" toMany="true">
+        <db-attribute-pair source="ID" target="X_ID"/>
+    </db-relationship>
+    <db-relationship name="toX" source="X_Y" target="X" toMany="false">
+        <db-attribute-pair source="X_ID" target="ID"/>
+    </db-relationship>
+    <db-relationship name="toY" source="X_Y" target="Y" toMany="false">
+        <db-attribute-pair source="Y_ID" target="ID"/>
+    </db-relationship>
+    <db-relationship name="xYArray" source="Y" target="X_Y" toDependentPK="true" toMany="true">
+        <db-attribute-pair source="ID" target="Y_ID"/>
+    </db-relationship>
     <obj-relationship name="toA" source="AB" target="A" deleteRule="Nullify" db-relationship-path="toA"/>
     <obj-relationship name="aBArray" source="B" target="AB" deleteRule="Deny" db-relationship-path="aBArray"/>
+    <obj-relationship name="yArray" source="X" target="Y" db-relationship-path="xYArray.toY"/>
+    <obj-relationship name="xArray" source="Y" target="X" db-relationship-path="xYArray.toX"/>
 </data-map>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54997aa6/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testUnFlattensManyToMany.sql
----------------------------------------------------------------------
diff --git a/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testUnFlattensManyToMany.sql b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testUnFlattensManyToMany.sql
index 57dae83..b6f4eac 100644
--- a/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testUnFlattensManyToMany.sql
+++ b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testUnFlattensManyToMany.sql
@@ -31,6 +31,7 @@ CREATE TABLE APP.A_B (
   A_ID INTEGER NOT NULL,
   B_ID INTEGER NOT NULL,
 
+  PRIMARY KEY (A_ID, B_ID),
   CONSTRAINT A_B_A FOREIGN KEY (A_ID) REFERENCES APP.A (ID),
   CONSTRAINT A_B_B FOREIGN KEY (B_ID) REFERENCES APP.B (ID)
 );
@@ -39,4 +40,25 @@ CREATE TABLE APP.C (
   id INTEGER NOT NULL,
 
   PRIMARY KEY (id)
+);
+
+CREATE TABLE APP.X (
+  id INTEGER NOT NULL,
+
+  PRIMARY KEY (id)
+);
+
+CREATE TABLE APP.Y (
+  id INTEGER NOT NULL,
+
+  PRIMARY KEY (id)
+);
+
+CREATE TABLE APP.X_Y (
+  X_ID INTEGER NOT NULL,
+  Y_ID INTEGER NOT NULL,
+
+  PRIMARY KEY (X_ID, Y_ID),
+  CONSTRAINT X_Y_X FOREIGN KEY (X_ID) REFERENCES APP.X (ID),
+  CONSTRAINT X_Y_Y FOREIGN KEY (Y_ID) REFERENCES APP.Y (ID)
 );
\ No newline at end of file


Mime
View raw message