Hello,

I was using to-one relationships as primary keys and found that it
wasn't working. I made it working, the right way, I hope ;-).

This patch modifies DataDomainInsertBucket.

The second is to fix a problem I had with DB2/AS400 using custom
templates to fetch DataObjects : the column names returned by the server
were in upper case, and Cayenne was expecting them in lower-case. My fix
is to normalize the keys in the DataRow, overriding get/put methods. I
think SQL is case insensitive for schema/table/column names, so it
shouldn't be a problem with any DBMS (again, I hope).

This patch modifies DataRow.

Cheers,

-- 
  .~.
  /V\      Mikaël Cluseau <[EMAIL PROTECTED]>
 // \\
/(   )\    ISI.NC             +687 26.93.18
 ^`~'^
Index: cayenne-java/src/cayenne/java/org/apache/cayenne/DataRow.java
===================================================================
--- cayenne-java/src/cayenne/java/org/apache/cayenne/DataRow.java	(revision 603157)
+++ cayenne-java/src/cayenne/java/org/apache/cayenne/DataRow.java	(working copy)
@@ -24,7 +24,6 @@
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.lang.builder.ToStringBuilder;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbRelationship;
@@ -30,6 +29,7 @@
 import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.util.Util;
+import org.apache.commons.lang.builder.ToStringBuilder;
 
 /**
  * DataRow a map that holds values retrieved from the database for a given query row.
@@ -41,6 +41,8 @@
  */
 public class DataRow extends HashMap {
 
+    private static final long serialVersionUID = 4985193658466841633L;
+
     // "volatile" is supposed to ensure consistency in read and increment operations;
     // is this universally true?
 
@@ -243,4 +245,25 @@
                 " version",
                 version).append(" replaces", replacesVersion).toString();
     }
+    
+    /*
+     * Caseless matching
+     */
+
+    public Object put(Object key, Object value) {
+        return super.put(normalizeKey(key), value);
+    }
+    
+    public Object get(Object key) {
+        return super.get(normalizeKey(key));
+    }
+
+    private String normalizeKey(Object key) {
+        String k = (String) key;
+        if (k != null) {
+            k = k.toLowerCase();
+        }
+        return k;
+    }
+
 }
Index: cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataDomainInsertBucket.java
===================================================================
--- cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataDomainInsertBucket.java	(revision 603157)
+++ cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataDomainInsertBucket.java	(working copy)
@@ -36,6 +36,7 @@
 import org.apache.cayenne.map.EntitySorter;
 import org.apache.cayenne.map.ObjAttribute;
 import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.ObjRelationship;
 import org.apache.cayenne.query.InsertBatchQuery;
 
 /**
@@ -145,6 +146,35 @@
                     idMap.put(dbAttrName, object.readPropertyDirectly(objAttr.getName()));
                     continue;
                 }
+                
+                // handle PKs behind to-one relationships
+                boolean found = false;
+                for (Iterator relIter = dbEntity.getRelationships().iterator(); relIter
+                        .hasNext();) {
+                    DbRelationship relationship = (DbRelationship) relIter.next();
+                    if (relationship.isToMany())
+                        continue;
+                    for (Iterator joinIter = relationship.getJoins().iterator(); joinIter
+                            .hasNext();) {
+                        DbJoin join = (DbJoin) joinIter.next();
+                        if (join.getSourceName().equals(dbAttrName)) {
+                            ObjRelationship objRel = objEntity
+                                    .getRelationshipForDbRelationship(relationship);
+                            DataObject target = (DataObject) object.readProperty(objRel
+                                    .getName());
+                            idMap.put(dbAttrName, target
+                                    .getObjectId()
+                                    .getIdSnapshot()
+                                    .get(join.getTargetName()));
+                            found = true;
+                            break;
+                        }
+                    }
+                    if (found)
+                        break;
+                }
+                if (found)
+                    continue;
 
                 // only a single key can be generated from DB... if this is done already
                 // in this loop, we must bail out.

Reply via email to