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.