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 2009/02/01 15:04:02 UTC

svn commit: r739765 - in /cayenne/main/trunk: docs/doc/src/main/resources/ framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/naming/ framework/cayenne...

Author: aadamchik
Date: Sun Feb  1 14:04:01 2009
New Revision: 739765

URL: http://svn.apache.org/viewvc?rev=739765&view=rev
Log:
CAY-1174 Modeler: support optional meaningful PK mapping during reverse engineering

patch by Dima Loiko , reworked by me to use consistent naming and implement  a cleaner test flow

Modified:
    cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DbLoader.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/naming/NamingStrategy.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DbLoaderPartialTest.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DbLoaderTest.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderOptionsDialog.java

Modified: cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt?rev=739765&r1=739764&r2=739765&view=diff
==============================================================================
--- cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt (original)
+++ cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt Sun Feb  1 14:04:01 2009
@@ -15,6 +15,7 @@
 Changes/New Features Since M5:
 
 CAY-1021 adding a callback method should result in focus on method name
+CAY-1047 Aligning query capabilities
 CAY-1140 Store ObjEntity name in the DataRow
 CAY-1142 (Single table) Inheritance and Paginated lists 
 CAY-1146 Move User properties API to ObjectContext & BaseContext
@@ -23,8 +24,8 @@
 CAY-1154 Rename .access.reveng package to .map.naming
 CAY-1156 Modeler search improvement
 CAY-1161 Deprecate SelectQuery custom columns feature
+CAY-1174 Modeler: support optional meaningful PK mapping during reverse engineering
 CAY-1175 Replace String column name capitalization property with an enum
-CAY-1047 Aligning query capabilities
 
 Bug Fixes Since M5:
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DbLoader.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DbLoader.java?rev=739765&r1=739764&r2=739765&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DbLoader.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DbLoader.java Sun Feb  1 14:04:01 2009
@@ -17,7 +17,6 @@
  *  under the License.
  ****************************************************************/
 
-
 package org.apache.cayenne.access;
 
 import java.sql.Connection;
@@ -58,7 +57,6 @@
 /**
  * Utility class that does reverse engineering of the database. It can create DataMaps
  * using database meta data obtained via JDBC driver.
- * 
  */
 public class DbLoader {
 
@@ -67,20 +65,20 @@
     // TODO: remove this hardcoded stuff once delegate starts to support procedure
     // loading...
     private static final Collection<String> EXCLUDED_PROCEDURES = Arrays.asList(
-            "auto_pk_for_table", "auto_pk_for_table;1" /*
-                                                         * the last name is some Mac OS X
-                                                         * Sybase artifact
-                                                         */
+            "auto_pk_for_table",
+            "auto_pk_for_table;1" /*
+                                   * the last name is some Mac OS X Sybase artifact
+                                   */
     );
 
     public static final String WILDCARD = "%";
 
     /** List of db entities to process. */
     private List<DbEntity> dbEntityList = new ArrayList<DbEntity>();
-    
+
     /**
-     * CAY-479 - need to track which entities are skipped in 
-     * the loader so that relationships to non-skipped entities can be loaded 
+     * CAY-479 - need to track which entities are skipped in the loader so that
+     * relationships to non-skipped entities can be loaded
      */
     private Set<DbEntity> skippedEntities = new HashSet<DbEntity>();
 
@@ -89,35 +87,44 @@
         int currentSuffix = 1;
         String relName = preferredName;
 
-        while (entity.getRelationship(relName) != null || entity.getAttribute(relName) != null) {
+        while (entity.getRelationship(relName) != null
+                || entity.getAttribute(relName) != null) {
             relName = preferredName + currentSuffix;
             currentSuffix++;
         }
         return relName;
     }
 
-    protected Connection con;
+    protected Connection connection;
     protected DbAdapter adapter;
     protected DatabaseMetaData metaData;
     protected DbLoaderDelegate delegate;
     protected String genericClassName;
-    
+    protected boolean creatingMeaningfulPK;
+
     /**
      * Strategy for choosing names for entities, attributes and relationships
      */
     protected NamingStrategy namingStrategy;
 
-    /** Creates new DbLoader. */
-    public DbLoader(Connection con, DbAdapter adapter, DbLoaderDelegate delegate) {
-        this(con, adapter, delegate, new BasicNamingStrategy());
-    }
-    
-    /** Creates new DbLoader with specified naming strategy. */
-    public DbLoader(Connection con, DbAdapter adapter, DbLoaderDelegate delegate, NamingStrategy strategy) {
+    /**
+     * Creates new DbLoader.
+     */
+    public DbLoader(Connection connection, DbAdapter adapter, DbLoaderDelegate delegate) {
+        this(connection, adapter, delegate, new BasicNamingStrategy());
+    }
+
+    /**
+     * Creates new DbLoader with specified naming strategy.
+     * 
+     * @since 3.0
+     */
+    public DbLoader(Connection connection, DbAdapter adapter, DbLoaderDelegate delegate,
+            NamingStrategy strategy) {
         this.adapter = adapter;
-        this.con = con;
+        this.connection = connection;
         this.delegate = delegate;
-        
+
         setNamingStrategy(strategy);
     }
 
@@ -126,22 +133,44 @@
      */
     public DatabaseMetaData getMetaData() throws SQLException {
         if (null == metaData)
-            metaData = con.getMetaData();
+            metaData = connection.getMetaData();
         return metaData;
     }
 
+    public void setCreatingMeaningfulPK(boolean check) {
+        this.creatingMeaningfulPK = check;
+    }
+
+    /**
+     * Returns true if the generator should map all primary key columns as ObjAttributes.
+     * 
+     * @since 3.0
+     */
+    public boolean isCreatingMeaningfulPK() {
+        return creatingMeaningfulPK;
+    }
+
     /**
      * Returns database connection used by this DbLoader.
+     * 
+     * @since 3.0
+     */
+    public Connection getConnection() {
+        return connection;
+    }
+
+    /**
+     * @deprecated since 3.0 in favor of {@link #getConnection()}.
      */
     public Connection getCon() {
-        return con;
+        return getConnection();
     }
 
     /**
      * Returns a name of a generic class that should be used for all ObjEntities. The most
-     * common generic class is {@link org.apache.cayenne.CayenneDataObject}. If
-     * generic class name is null (which is the default), DbLoader will assign each entity
-     * a unique class name derived from the table name.
+     * common generic class is {@link org.apache.cayenne.CayenneDataObject}. If generic
+     * class name is null (which is the default), DbLoader will assign each entity a
+     * unique class name derived from the table name.
      * 
      * @since 1.2
      */
@@ -151,9 +180,9 @@
 
     /**
      * Sets a name of a generic class that should be used for all ObjEntities. The most
-     * common generic class is {@link org.apache.cayenne.CayenneDataObject}. If
-     * generic class name is set to null (which is the default), DbLoader will assign each
-     * entity a unique class name derived from the table name.
+     * common generic class is {@link org.apache.cayenne.CayenneDataObject}. If generic
+     * class name is set to null (which is the default), DbLoader will assign each entity
+     * a unique class name derived from the table name.
      * 
      * @since 1.2
      */
@@ -169,10 +198,10 @@
     public DbAdapter getAdapter() {
         return adapter;
     }
-    
+
     /**
      * A method that return true if the given table name should be included. The default
-     * implemntation include all tables.
+     * implementation include all tables.
      */
     public boolean includeTableName(String tableName) {
         return true;
@@ -297,7 +326,7 @@
                 if (name == null || name.startsWith("BIN$")) {
                     continue;
                 }
-                
+
                 if (!includeTableName(name)) {
                     continue;
                 }
@@ -322,7 +351,8 @@
      *            DbEntities must be created.
      * @return false if loading must be immediately aborted.
      */
-    public boolean loadDbEntities(DataMap map, List<? extends DbEntity> tables) throws SQLException {
+    public boolean loadDbEntities(DataMap map, List<? extends DbEntity> tables)
+            throws SQLException {
         this.dbEntityList = new ArrayList<DbEntity>();
 
         for (DbEntity dbEntity : tables) {
@@ -359,7 +389,6 @@
                 }
             }
 
-
             // Create DbAttributes from column information --
             ResultSet rs = getMetaData().getColumns(
                     dbEntity.getCatalog(),
@@ -424,12 +453,12 @@
             }
 
             // delegate might have thrown this entity out... so check if it is still
-            // around  before continuing processing
+            // around before continuing processing
             if (map.getDbEntity(dbEntity.getName()) == dbEntity) {
                 this.dbEntityList.add(dbEntity);
             }
         }
-        
+
         // get primary keys for each table and store it in dbEntity
         for (final DbEntity dbEntity : map.getDbEntities()) {
             String tableName = dbEntity.getName();
@@ -455,14 +484,14 @@
                 rs.close();
             }
         }
-        
+
         // cay-479 - iterate skipped DbEntities to populate exported keys
         for (final DbEntity skippedEntity : skippedEntities) {
             loadDbRelationships(skippedEntity, map);
         }
-            
+
         return true;
-        
+
     }
 
     /**
@@ -513,7 +542,6 @@
                     : packageName + objEntity.getName());
             map.addObjEntity(objEntity);
             loadedEntities.add(objEntity);
-
             // added entity without attributes or relationships...
             if (delegate != null) {
                 delegate.objEntityAdded(objEntity);
@@ -521,7 +549,8 @@
         }
 
         // update ObjEntity attributes and relationships
-        new EntityMergeSupport(map, namingStrategy).synchronizeWithDbEntities(loadedEntities);
+        new EntityMergeSupport(map, namingStrategy, !creatingMeaningfulPK)
+                .synchronizeWithDbEntities(loadedEntities);
     }
 
     /** Loads database relationships into a DataMap. */
@@ -539,16 +568,12 @@
         ResultSet rs = null;
 
         try {
-            rs = md.getExportedKeys(
-                    pkEntity.getCatalog(),
-                    pkEntity.getSchema(),
-                    pkEntity.getName());
+            rs = md.getExportedKeys(pkEntity.getCatalog(), pkEntity.getSchema(), pkEntity
+                    .getName());
         }
         catch (SQLException cay182Ex) {
             // Sybase-specific - the line above blows on VIEWS, see CAY-182.
-            logObj.info("Error getting relationships for '"
-                    + pkEntName
-                    + "', ignoring.");
+            logObj.info("Error getting relationships for '" + pkEntName + "', ignoring.");
             return;
         }
 
@@ -565,9 +590,9 @@
             ExportedKey key = null;
 
             do {
-                //extract data from resultset
+                // extract data from resultset
                 key = ExportedKey.extractData(rs);
-                
+
                 short keySeq = rs.getShort("KEY_SEQ");
                 if (keySeq == 1) {
 
@@ -579,33 +604,38 @@
                     // start new entity
                     String fkEntityName = key.getFKTableName();
                     String fkName = key.getFKName();
-                    
+
                     if (!includeTableName(fkEntityName)) {
                         continue;
                     }
-                    
+
                     fkEntity = map.getDbEntity(fkEntityName);
 
                     if (fkEntity == null) {
                         logObj.info("FK warning: no entity found for name '"
                                 + fkEntityName
                                 + "'");
-                    } else if (skippedEntities.contains(pkEntity) && skippedEntities.contains(fkEntity)) {
+                    }
+                    else if (skippedEntities.contains(pkEntity)
+                            && skippedEntities.contains(fkEntity)) {
                         // cay-479 - don't load relationships between two
                         // skipped entities.
                         continue;
                     }
                     else {
                         // init relationship
-                        String forwardPreferredName = namingStrategy.createDbRelationshipName(key, true);
-                        forwardRelationship = new DbRelationship(
-                                uniqueRelName(pkEntity, forwardPreferredName));
+                        String forwardPreferredName = namingStrategy
+                                .createDbRelationshipName(key, true);
+                        forwardRelationship = new DbRelationship(uniqueRelName(
+                                pkEntity,
+                                forwardPreferredName));
 
                         forwardRelationship.setSourceEntity(pkEntity);
                         forwardRelationship.setTargetEntity(fkEntity);
                         pkEntity.addRelationship(forwardRelationship);
 
-                        String reversePreferredName = namingStrategy.createDbRelationshipName(key, false);
+                        String reversePreferredName = namingStrategy
+                                .createDbRelationshipName(key, false);
                         reverseRelationship = new DbRelationshipDetected(uniqueRelName(
                                 fkEntity,
                                 reversePreferredName));
@@ -625,15 +655,13 @@
                     // skip invalid joins...
                     DbAttribute pkAtt = (DbAttribute) pkEntity.getAttribute(pkName);
                     if (pkAtt == null) {
-                        logObj.info("no attribute for declared primary key: "
-                                + pkName);
+                        logObj.info("no attribute for declared primary key: " + pkName);
                         continue;
                     }
 
                     DbAttribute fkAtt = (DbAttribute) fkEntity.getAttribute(fkName);
                     if (fkAtt == null) {
-                        logObj.info("no attribute for declared foreign key: "
-                                + fkName);
+                        logObj.info("no attribute for declared foreign key: " + fkName);
                         continue;
                     }
 
@@ -658,11 +686,14 @@
             rs.close();
         }
     }
+
     /**
      * Detects correct relationship multiplicity and "to dep pk" flag. Only called on
      * relationships from PK to FK, not the reverse ones.
      */
-    protected void postprocessMasterDbRelationship(DbRelationship relationship, ExportedKey key) {
+    protected void postprocessMasterDbRelationship(
+            DbRelationship relationship,
+            ExportedKey key) {
         boolean toPK = true;
         List<DbJoin> joins = relationship.getJoins();
 
@@ -689,8 +720,8 @@
         if (!toMany) {
             Entity source = relationship.getSourceEntity();
             source.removeRelationship(relationship.getName());
-            relationship.setName(DbLoader.uniqueRelName(source, 
-                    namingStrategy.createDbRelationshipName(key, false)));
+            relationship.setName(DbLoader.uniqueRelName(source, namingStrategy
+                    .createDbRelationshipName(key, false)));
             source.addRelationship(relationship);
         }
 
@@ -919,21 +950,24 @@
             dataMap.addProcedure(procedure);
         }
     }
-    
+
     /**
      * Sets new naming strategy for reverse engineering
+     * 
+     * @since 3.0
      */
     public void setNamingStrategy(NamingStrategy strategy) {
-        //null values are not allowed
+        // null values are not allowed
         if (strategy == null) {
             throw new NullPointerException("Null strategy not allowed");
         }
-        
+
         this.namingStrategy = strategy;
     }
-    
+
     /**
      * @return naming strategy for reverse engineering
+     * @since 3.0
      */
     public NamingStrategy getNamingStrategy() {
         return namingStrategy;

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/naming/NamingStrategy.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/naming/NamingStrategy.java?rev=739765&r1=739764&r2=739765&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/naming/NamingStrategy.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/naming/NamingStrategy.java Sun Feb  1 14:04:01 2009
@@ -29,25 +29,24 @@
  * @since 3.0
  */
 public interface NamingStrategy {
+
     /**
-     * Creates new name for Obj Entity 
+     * Creates new name for Obj Entity
      */
-    public String createObjEntityName(DbEntity entity);
-    
+    String createObjEntityName(DbEntity entity);
+
     /**
-     * Creates new name for Obj Attribute 
+     * Creates new name for Obj Attribute
      */
-    public String createObjAttributeName(DbAttribute attr);
-    
+    String createObjAttributeName(DbAttribute attr);
+
     /**
-     * Creates new name for Db Relationship 
+     * Creates new name for Db Relationship
      */
-    public String createDbRelationshipName(
-            ExportedKey key,
-            boolean toMany);
-    
+    String createDbRelationshipName(ExportedKey key, boolean toMany);
+
     /**
-     * Creates new name for Obj Relationship 
+     * Creates new name for Obj Relationship
      */
-    public String createObjRelationshipName(DbRelationship dbRel);
+    String createObjRelationshipName(DbRelationship dbRel);
 }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java?rev=739765&r1=739764&r2=739765&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java Sun Feb  1 14:04:01 2009
@@ -40,36 +40,41 @@
 
 /**
  * Implements methods for entity merging.
- * 
  */
 public class EntityMergeSupport {
 
     protected DataMap map;
     protected boolean removeMeaningfulFKs;
-    
+    protected boolean removeMeaningfulPKs;
+
     /**
      * Strategy for choosing names for entities, attributes and relationships
      */
     protected NamingStrategy namingStrategy;
-    
+
     /**
-     * Listeners of merge process. 
+     * Listeners of merge process.
      */
     protected List<EntityMergeListener> listeners;
-    
+
     public EntityMergeSupport(DataMap map) {
-        this(map, new BasicNamingStrategy()); 
+        this(map, new BasicNamingStrategy(), true);
     }
-    
-    public EntityMergeSupport(DataMap map, NamingStrategy namingStrategy) {
+
+    /**
+     * @since 3.0
+     */
+    public EntityMergeSupport(DataMap map, NamingStrategy namingStrategy,
+            boolean removeMeaningfulPKs) {
         this.map = map;
         this.removeMeaningfulFKs = true;
-        this.listeners = new ArrayList<EntityMergeListener>(); 
-        
+        this.listeners = new ArrayList<EntityMergeListener>();
+        this.removeMeaningfulPKs = removeMeaningfulPKs;
         this.namingStrategy = namingStrategy;
-        
+
         /**
-         * Adding a listener, so that all created ObjRelationships would have default delete rule
+         * Adding a listener, so that all created ObjRelationships would have default
+         * delete rule
          */
         addEntityMergeListener(DeleteRuleUpdater.getEntityMergeListener());
     }
@@ -79,7 +84,6 @@
      * relationships based on the current state of its DbEntity.
      * 
      * @return true if any ObjEntity has changed as a result of synchronization.
-     * 
      * @since 1.2 changed signature to use Collection instead of List.
      */
     public boolean synchronizeWithDbEntities(Collection<ObjEntity> objEntities) {
@@ -128,8 +132,8 @@
 
             // add missing attributes
             for (DbAttribute da : getAttributesToAdd(entity)) {
-                String attrName = namingStrategy.createObjAttributeName(da);
 
+                String attrName = namingStrategy.createObjAttributeName(da);
                 // avoid duplicate names
                 attrName = NamedObjectFactory.createName(
                         ObjAttribute.class,
@@ -141,7 +145,6 @@
                 ObjAttribute oa = new ObjAttribute(attrName, type, entity);
                 oa.setDbAttributePath(da.getName());
                 entity.addAttribute(oa);
-                
                 fireAttributeAdded(oa);
                 changed = true;
             }
@@ -153,7 +156,8 @@
                 for (Entity mappedTarget : map.getMappedEntities(dbEntity)) {
 
                     // avoid duplicate names
-                    String relationshipName = namingStrategy.createObjRelationshipName(dr);
+                    String relationshipName = namingStrategy
+                            .createObjRelationshipName(dr);
                     relationshipName = NamedObjectFactory.createName(
                             ObjRelationship.class,
                             entity,
@@ -164,7 +168,7 @@
                     or.setSourceEntity(entity);
                     or.setTargetEntity(mappedTarget);
                     entity.addRelationship(or);
-                    
+
                     fireRelationshipAdded(or);
                     changed = true;
                 }
@@ -201,7 +205,8 @@
     protected List<DbAttribute> getAttributesToAdd(ObjEntity objEntity) {
         List<DbAttribute> missing = new ArrayList<DbAttribute>();
         Collection<DbRelationship> rels = objEntity.getDbEntity().getRelationships();
-        Collection<DbRelationship> incomingRels = getIncomingRelationships(objEntity.getDbEntity());
+        Collection<DbRelationship> incomingRels = getIncomingRelationships(objEntity
+                .getDbEntity());
 
         for (DbAttribute dba : objEntity.getDbEntity().getAttributes()) {
             // already there
@@ -210,8 +215,15 @@
             }
 
             // check if adding it makes sense at all
-            if (dba.getName() == null || dba.isPrimaryKey()) {
-                continue;
+            if (!removeMeaningfulPKs) {
+                if (dba.getName() == null) {
+                    continue;
+                }
+            }
+            else {
+                if (dba.getName() == null || dba.isPrimaryKey()) {
+                    continue;
+                }
             }
 
             // check FK's
@@ -227,10 +239,17 @@
                 }
             }
 
-            if (isFK) {
-                continue;
+            if (!removeMeaningfulPKs) {
+                if (!dba.isPrimaryKey() && isFK) {
+                    continue;
+                }
             }
-            
+            else {
+                if (isFK) {
+                    continue;
+                }
+            }
+
             // check incoming relationships
             rit = incomingRels.iterator();
             while (!isFK && rit.hasNext()) {
@@ -242,9 +261,16 @@
                     }
                 }
             }
-            
-            if (isFK) {
-                continue;
+
+            if (!removeMeaningfulPKs) {
+                if (!dba.isPrimaryKey() && isFK) {
+                    continue;
+                }
+            }
+            else {
+                if (isFK) {
+                    continue;
+                }
             }
 
             missing.add(dba);
@@ -252,10 +278,10 @@
 
         return missing;
     }
-    
+
     private Collection<DbRelationship> getIncomingRelationships(DbEntity entity) {
         Collection<DbRelationship> incoming = new ArrayList<DbRelationship>();
-        
+
         for (DbEntity nextEntity : entity.getDataMap().getDbEntities()) {
             for (DbRelationship relationship : nextEntity.getRelationships()) {
                 if (entity == relationship.getTargetEntity()) {
@@ -263,7 +289,7 @@
                 }
             }
         }
-        
+
         return incoming;
     }
 
@@ -304,28 +330,28 @@
     public void setRemoveMeaningfulFKs(boolean removeMeaningfulFKs) {
         this.removeMeaningfulFKs = removeMeaningfulFKs;
     }
-    
+
     /**
      * Registers new EntityMergeListener
      */
     public void addEntityMergeListener(EntityMergeListener listener) {
         listeners.add(listener);
     }
-    
+
     /**
      * Unregisters an EntityMergeListener
      */
     public void removeEntityMergeListener(EntityMergeListener listener) {
         listeners.remove(listener);
     }
-    
+
     /**
      * Returns registered listeners
      */
     public EntityMergeListener[] getEntityMergeListeners() {
         return listeners.toArray(new EntityMergeListener[0]);
     }
-    
+
     /**
      * Notifies all listeners that an ObjAttribute was added
      */
@@ -334,7 +360,7 @@
             listeners.get(i).objAttributeAdded(attr);
         }
     }
-    
+
     /**
      * Notifies all listeners that an ObjRelationship was added
      */
@@ -343,14 +369,14 @@
             listeners.get(i).objRelationshipAdded(rel);
         }
     }
-    
+
     /**
      * Sets new naming strategy for reverse engineering
      */
     public void setNamingStrategy(NamingStrategy strategy) {
         this.namingStrategy = strategy;
     }
-    
+
     /**
      * @return naming strategy for reverse engineering
      */

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DbLoaderPartialTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DbLoaderPartialTest.java?rev=739765&r1=739764&r2=739765&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DbLoaderPartialTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DbLoaderPartialTest.java Sun Feb  1 14:04:01 2009
@@ -112,7 +112,7 @@
 
         }
         finally {
-            loader.getCon().close();
+            loader.getConnection().close();
         }
     }
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DbLoaderTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DbLoaderTest.java?rev=739765&r1=739764&r2=739765&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DbLoaderTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DbLoaderTest.java Sun Feb  1 14:04:01 2009
@@ -40,7 +40,6 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-
         loader = new DbLoader(getConnection(), getNode().getAdapter(), null);
     }
 
@@ -65,7 +64,7 @@
             }
         }
         finally {
-            loader.getCon().close();
+            loader.getConnection().close();
         }
     }
 
@@ -92,7 +91,33 @@
             assertTrue("'ARTIST' is missing from the table list: " + tables, foundArtist);
         }
         finally {
-            loader.getCon().close();
+            loader.getConnection().close();
+        }
+    }
+
+    public void testLoadWithMeaningfulPK() throws Exception {
+        try {
+
+            DataMap map = new DataMap();
+            String tableLabel = getNode().getAdapter().tableTypeForTable();
+
+            loader.setCreatingMeaningfulPK(true);
+            loader.loadDbEntities(map, loader.getTables(
+                    null,
+                    null,
+                    "ARTIST",
+                    new String[] {
+                        tableLabel
+                    }));
+
+            loader.loadObjEntities(map);
+            ObjEntity artist = map.getObjEntity("Artist");
+            assertNotNull(artist);
+            ObjAttribute id = (ObjAttribute) artist.getAttribute("artistId");
+            assertNotNull(id);
+        }
+        finally {
+            loader.getConnection().close();
         }
     }
 
@@ -157,7 +182,9 @@
             }
 
             // *** TESTING THIS ***
+            loader.setCreatingMeaningfulPK(false);
             loader.loadObjEntities(map);
+
             ObjEntity ae = map.getObjEntity("Artist");
             assertNotNull(ae);
             assertEquals("Artist", ae.getName());
@@ -181,7 +208,7 @@
             }
         }
         finally {
-            loader.getCon().close();
+            loader.getConnection().close();
         }
     }
 

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java?rev=739765&r1=739764&r2=739765&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java Sun Feb  1 14:04:01 2009
@@ -77,6 +77,7 @@
     protected String schemaName;
     protected String tableNamePattern;
     protected boolean loadProcedures;
+    protected boolean meaningfulPk;
     protected String procedureNamePattern;
     protected List schemas;
 
@@ -171,6 +172,7 @@
         this.schemaName = dialog.getSelectedSchema();
         this.tableNamePattern = dialog.getTableNamePattern();
         this.loadProcedures = dialog.isLoadingProcedures();
+        this.meaningfulPk = dialog.isMeaningfulPk();
         this.procedureNamePattern = dialog.getProcedureNamePattern();
         this.addedObjEntities = new ArrayList<ObjEntity>();
         
@@ -197,8 +199,8 @@
     protected void cleanup() {
         loadStatusNote = "Closing connection...";
         try {
-            if (loader.getCon() != null) {
-                loader.getCon().close();
+            if (loader.getConnection() != null) {
+                loader.getConnection().close();
             }
         }
         catch (SQLException e) {
@@ -365,6 +367,7 @@
             loadStatusNote = "Importing tables...";
 
             try {
+                loader.setCreatingMeaningfulPK(meaningfulPk);
                 loader.loadDataMapFromDB(schemaName, tableNamePattern, dataMap);
                 
                 /**

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderOptionsDialog.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderOptionsDialog.java?rev=739765&r1=739764&r2=739765&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderOptionsDialog.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderOptionsDialog.java Sun Feb  1 14:04:01 2009
@@ -24,7 +24,6 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.util.Collection;
-import java.util.Iterator;
 import java.util.Vector;
 
 import javax.swing.DefaultComboBoxModel;
@@ -78,6 +77,7 @@
     protected JComboBox schemaSelector;
     protected JTextField tableNamePatternField;
     protected JCheckBox loadProcedures;
+    protected JCheckBox meaningfulPk;
     protected JTextField procNamePatternField;
     protected JLabel procedureLabel;
     protected JButton selectButton;
@@ -119,7 +119,7 @@
         tableNamePatternField = new JTextField();
         procNamePatternField = new JTextField();
         loadProcedures = new JCheckBox();
-        
+        meaningfulPk = new JCheckBox(); 
         strategyCombo = new JComboBox();
         strategyCombo.setEditable(true);
 
@@ -135,7 +135,8 @@
         builder.append("Load Procedures:", loadProcedures);
         procedureLabel = builder.append("Procedure Name Pattern:", procNamePatternField);
         builder.append("Naming Strategy:", strategyCombo);
-
+        builder.append("Meaningful PK",meaningfulPk);
+        
         JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT));
         buttons.add(cancelButton);
         buttons.add(selectButton);
@@ -267,6 +268,10 @@
     public boolean isLoadingProcedures() {
         return loadProcedures.isSelected();
     }
+    
+    public boolean isMeaningfulPk() {
+        return meaningfulPk.isSelected();
+    }
 
     /**
      * Returns the procedure name pattern.