Author: aadamchik Date: Thu Nov 30 03:37:16 2006 New Revision: 480892 URL: http://svn.apache.org/viewvc?view=rev&rev=480892 Log: CAY-713: Improved Meaningful PK support (CAY-713 accomplished)
Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/CayenneDataObject.java incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainDBDiffBuilder.java incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainDeleteBucket.java incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainFlushAction.java incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainInsertBucket.java incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainSyncBucket.java incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainUpdateBucket.java incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/ClassDescriptor.java incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/LazyClassDescriptorDecorator.java incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/PersistentDescriptor.java incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/pojo/EnhancedPojoDescriptorFactory.java incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/access/DataContextEntityWithMeaningfulPKTest.java incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/reflect/MockClassDescriptor.java Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/CayenneDataObject.java URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/CayenneDataObject.java?view=diff&rev=480892&r1=480891&r2=480892 ============================================================================== --- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/CayenneDataObject.java (original) +++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/CayenneDataObject.java Thu Nov 30 03:37:16 2006 @@ -524,6 +524,11 @@ while (attributes.hasNext()) { ObjAttribute objAttribute = (ObjAttribute) attributes.next(); DbAttribute dbAttribute = objAttribute.getDbAttribute(); + + // pk may still be generated + if(dbAttribute.isPrimaryKey()) { + continue; + } Object value = this.readPropertyDirectly(objAttribute.getName()); if (dbAttribute.isMandatory()) { Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainDBDiffBuilder.java URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainDBDiffBuilder.java?view=diff&rev=480892&r1=480891&r2=480892 ============================================================================== --- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainDBDiffBuilder.java (original) +++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainDBDiffBuilder.java Thu Nov 30 03:37:16 2006 @@ -138,15 +138,10 @@ private void appendPrimaryKeys(Map dbDiff) { - // populate changed PKs, do not override values already set by users... + // populate changed PKs; note that we might end up overriding some values taken + // from the object (e.g. zero PK's). if (currentId != null) { - Iterator it = ((ObjectId) currentId).getIdSnapshot().entrySet().iterator(); - while (it.hasNext()) { - Map.Entry entry = (Map.Entry) it.next(); - if (!dbDiff.containsKey(entry.getKey())) { - dbDiff.put(entry.getKey(), entry.getValue()); - } - } + dbDiff.putAll(((ObjectId) currentId).getIdSnapshot()); } } Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainDeleteBucket.java URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainDeleteBucket.java?view=diff&rev=480892&r1=480891&r2=480892 ============================================================================== --- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainDeleteBucket.java (original) +++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainDeleteBucket.java Thu Nov 30 03:37:16 2006 @@ -31,8 +31,8 @@ import org.apache.cayenne.Persistent; import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.map.EntitySorter; -import org.apache.cayenne.map.ObjEntity; import org.apache.cayenne.query.DeleteBatchQuery; +import org.apache.cayenne.reflect.ClassDescriptor; /** * @since 1.2 @@ -46,11 +46,11 @@ void postprocess() { - if (!objectsByEntity.isEmpty()) { + if (!objectsByDescriptor.isEmpty()) { Collection deletedIds = parent.getResultDeletedIds(); - Iterator it = objectsByEntity.values().iterator(); + Iterator it = objectsByDescriptor.values().iterator(); while (it.hasNext()) { Iterator objects = ((Collection) it.next()).iterator(); while (objects.hasNext()) { @@ -70,28 +70,28 @@ for (Iterator i = dbEntities.iterator(); i.hasNext();) { DbEntity dbEntity = (DbEntity) i.next(); - List objEntitiesForDbEntity = (List) objEntitiesByDbEntity.get(dbEntity); + List objEntitiesForDbEntity = (List) descriptorsByDbEntity.get(dbEntity); Map batches = new LinkedHashMap(); for (Iterator j = objEntitiesForDbEntity.iterator(); j.hasNext();) { - ObjEntity entity = (ObjEntity) j.next(); + ClassDescriptor descriptor = (ClassDescriptor) j.next(); - qualifierBuilder.reset(entity, dbEntity); + qualifierBuilder.reset(descriptor.getEntity(), dbEntity); - boolean isRootDbEntity = (entity.getDbEntity() == dbEntity); + boolean isRootDbEntity = (descriptor.getEntity().getDbEntity() == dbEntity); // remove object set for dependent entity, so that it does not show up // on post processing - List objects = (List) objectsByEntity.get(entity); + List objects = (List) objectsByDescriptor.get(descriptor); if (objects.isEmpty()) { continue; } - checkReadOnly(entity); + checkReadOnly(descriptor.getEntity()); if (isRootDbEntity) { - sorter.sortObjectsForEntity(entity, objects, true); + sorter.sortObjectsForEntity(descriptor.getEntity(), objects, true); } for (Iterator k = objects.iterator(); k.hasNext();) { Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainFlushAction.java URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainFlushAction.java?view=diff&rev=480892&r1=480891&r2=480892 ============================================================================== --- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainFlushAction.java (original) +++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainFlushAction.java Thu Nov 30 03:37:16 2006 @@ -36,8 +36,8 @@ import org.apache.cayenne.graph.CompoundDiff; import org.apache.cayenne.graph.GraphDiff; import org.apache.cayenne.map.DbEntity; -import org.apache.cayenne.map.ObjEntity; import org.apache.cayenne.query.BatchQuery; +import org.apache.cayenne.reflect.ClassDescriptor; /** * A stateful commit handler used by DataContext to perform commit operation. @@ -161,18 +161,18 @@ while (it.hasNext()) { ObjectId id = (ObjectId) it.next(); Persistent object = (Persistent) objectStore.getNode(id); - ObjEntity entity = context.getEntityResolver().lookupObjEntity( + ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor( id.getEntityName()); switch (object.getPersistenceState()) { case PersistenceState.NEW: - insertBucket.addDirtyObject(object, entity); + insertBucket.addDirtyObject(object, descriptor); break; case PersistenceState.MODIFIED: - updateBucket.addDirtyObject(object, entity); + updateBucket.addDirtyObject(object, descriptor); break; case PersistenceState.DELETED: - deleteBucket.addDirtyObject(object, entity); + deleteBucket.addDirtyObject(object, descriptor); break; } } Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainInsertBucket.java URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainInsertBucket.java?view=diff&rev=480892&r1=480891&r2=480892 ============================================================================== --- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainInsertBucket.java (original) +++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainInsertBucket.java Thu Nov 30 03:37:16 2006 @@ -59,33 +59,32 @@ Iterator i = dbEntities.iterator(); while (i.hasNext()) { DbEntity dbEntity = (DbEntity) i.next(); - List objEntitiesForDbEntity = (List) objEntitiesByDbEntity.get(dbEntity); + List objEntitiesForDbEntity = (List) descriptorsByDbEntity.get(dbEntity); InsertBatchQuery batch = new InsertBatchQuery(dbEntity, 27); Iterator j = objEntitiesForDbEntity.iterator(); while (j.hasNext()) { - ObjEntity entity = (ObjEntity) j.next(); + ClassDescriptor descriptor = (ClassDescriptor) j.next(); - diffBuilder.reset(entity, dbEntity); + diffBuilder.reset(descriptor.getEntity(), dbEntity); - boolean isMasterDbEntity = (entity.getDbEntity() == dbEntity); + boolean isMasterDbEntity = (descriptor.getEntity().getDbEntity() == dbEntity); // remove object set for dependent entity, so that it does not show up // on post processing - List objects = (List) (isMasterDbEntity - ? objectsByEntity.get(entity) - : objectsByEntity.remove(entity)); + List objects = (List) (isMasterDbEntity ? objectsByDescriptor + .get(descriptor) : objectsByDescriptor.remove(descriptor)); if (objects.isEmpty()) { continue; } - checkReadOnly(entity); + checkReadOnly(descriptor.getEntity()); if (isMasterDbEntity) { - createPermIdsForObjEntity(entity, objects); - sorter.sortObjectsForEntity(entity, objects, false); + createPermIdsForObjEntity(descriptor, objects); + sorter.sortObjectsForEntity(descriptor.getEntity(), objects, false); } for (Iterator k = objects.iterator(); k.hasNext();) { @@ -102,12 +101,13 @@ } } - void createPermIdsForObjEntity(ObjEntity objEntity, List dataObjects) { + void createPermIdsForObjEntity(ClassDescriptor descriptor, List dataObjects) { if (dataObjects.isEmpty()) { return; } + ObjEntity objEntity = descriptor.getEntity(); DbEntity dbEntity = objEntity.getDbEntity(); DataNode node = parent.getDomain().lookupDataNode(dbEntity.getDataMap()); Collection generatedPks = getAutogeneratedKeys(node, dbEntity); @@ -117,7 +117,6 @@ } PkGenerator pkGenerator = node.getAdapter().getPkGenerator(); - ClassDescriptor descriptor = null; Iterator i = dataObjects.iterator(); while (i.hasNext()) { @@ -145,17 +144,17 @@ ObjAttribute objAttr = objEntity.getAttributeForDbAttribute(dbAttr); if (objAttr != null) { - if (descriptor == null) { - descriptor = parent - .getDomain() - .getEntityResolver() - .getClassDescriptor(objEntity.getName()); - } - - idMap.put(dbAttrName, descriptor + Object value = descriptor .getProperty(objAttr.getName()) - .readPropertyDirectly(object)); - continue; + .readPropertyDirectly(object); + + if (value != null) { + // treat numeric zero values as nulls requiring generation + if (!(value instanceof Number && ((Number) value).intValue() == 0)) { + idMap.put(dbAttrName, value); + continue; + } + } } // only a single key can be generated from DB... if this is done already Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainSyncBucket.java URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainSyncBucket.java?view=diff&rev=480892&r1=480891&r2=480892 ============================================================================== --- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainSyncBucket.java (original) +++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainSyncBucket.java Thu Nov 30 03:37:16 2006 @@ -37,6 +37,8 @@ import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.map.ObjAttribute; import org.apache.cayenne.map.ObjEntity; +import org.apache.cayenne.reflect.AttributeProperty; +import org.apache.cayenne.reflect.ClassDescriptor; /** * A superclass of batch query wrappers. @@ -46,19 +48,19 @@ */ abstract class DataDomainSyncBucket { - final Map objectsByEntity; + final Map objectsByDescriptor; final DataDomainFlushAction parent; List dbEntities; - Map objEntitiesByDbEntity; + Map descriptorsByDbEntity; DataDomainSyncBucket(DataDomainFlushAction parent) { - this.objectsByEntity = new HashMap(); + this.objectsByDescriptor = new HashMap(); this.parent = parent; } boolean isEmpty() { - return objectsByEntity.isEmpty(); + return objectsByDescriptor.isEmpty(); } abstract void appendQueriesInternal(Collection queries); @@ -68,7 +70,7 @@ */ void appendQueries(Collection queries) { - if (!objectsByEntity.isEmpty()) { + if (!objectsByDescriptor.isEmpty()) { groupObjEntitiesBySpannedDbEntities(); appendQueriesInternal(queries); } @@ -94,55 +96,55 @@ private void groupObjEntitiesBySpannedDbEntities() { - dbEntities = new ArrayList(objectsByEntity.size()); - objEntitiesByDbEntity = new HashMap(objectsByEntity.size() * 2); + dbEntities = new ArrayList(objectsByDescriptor.size()); + descriptorsByDbEntity = new HashMap(objectsByDescriptor.size() * 2); - Iterator i = objectsByEntity.keySet().iterator(); + Iterator i = objectsByDescriptor.keySet().iterator(); while (i.hasNext()) { - ObjEntity objEntity = (ObjEntity) i.next(); - DbEntity dbEntity = objEntity.getDbEntity(); + ClassDescriptor descriptor = (ClassDescriptor) i.next(); + DbEntity dbEntity = descriptor.getEntity().getDbEntity(); - List objEntitiesForDbEntity = (List) objEntitiesByDbEntity.get(dbEntity); + List objEntitiesForDbEntity = (List) descriptorsByDbEntity.get(dbEntity); if (objEntitiesForDbEntity == null) { objEntitiesForDbEntity = new ArrayList(1); dbEntities.add(dbEntity); - objEntitiesByDbEntity.put(dbEntity, objEntitiesForDbEntity); + descriptorsByDbEntity.put(dbEntity, objEntitiesForDbEntity); } - if (!objEntitiesForDbEntity.contains(objEntity)) { - objEntitiesForDbEntity.add(objEntity); + if (!objEntitiesForDbEntity.contains(descriptor)) { + objEntitiesForDbEntity.add(descriptor); } // Note that this logic won't allow flattened attributes to span multiple // databases... - Iterator j = objEntity.getAttributeMap().values().iterator(); + Iterator j = descriptor.getEntity().getAttributeMap().values().iterator(); while (j.hasNext()) { ObjAttribute objAttribute = (ObjAttribute) j.next(); if (!objAttribute.isCompound()) continue; dbEntity = (DbEntity) objAttribute.getDbAttribute().getEntity(); - objEntitiesForDbEntity = (List) objEntitiesByDbEntity.get(dbEntity); + objEntitiesForDbEntity = (List) descriptorsByDbEntity.get(dbEntity); if (objEntitiesForDbEntity == null) { objEntitiesForDbEntity = new ArrayList(1); dbEntities.add(dbEntity); - objEntitiesByDbEntity.put(dbEntity, objEntitiesForDbEntity); + descriptorsByDbEntity.put(dbEntity, objEntitiesForDbEntity); } - if (!objEntitiesForDbEntity.contains(objEntity)) { - objEntitiesForDbEntity.add(objEntity); + if (!objEntitiesForDbEntity.contains(descriptor)) { + objEntitiesForDbEntity.add(descriptor); } } } } - void addDirtyObject(Object object, ObjEntity entity) { + void addDirtyObject(Object object, ClassDescriptor descriptor) { - Collection objects = (Collection) objectsByEntity.get(entity); + Collection objects = (Collection) objectsByDescriptor.get(descriptor); if (objects == null) { objects = new ArrayList(); - objectsByEntity.put(entity, objects); + objectsByDescriptor.put(descriptor, objects); } objects.add(object); @@ -150,16 +152,19 @@ void postprocess() { - if (!objectsByEntity.isEmpty()) { + if (!objectsByDescriptor.isEmpty()) { CompoundDiff result = parent.getResultDiff(); Map modifiedSnapshots = parent.getResultModifiedSnapshots(); Collection deletedIds = parent.getResultDeletedIds(); - Iterator it = objectsByEntity.values().iterator(); + Iterator it = objectsByDescriptor.entrySet().iterator(); while (it.hasNext()) { - Iterator objects = ((Collection) it.next()).iterator(); + Map.Entry entry = (Map.Entry) it.next(); + ClassDescriptor descriptor = (ClassDescriptor) entry.getKey(); + + Iterator objects = ((Collection) entry.getValue()).iterator(); while (objects.hasNext()) { Persistent object = (Persistent) objects.next(); ObjectId id = object.getObjectId(); @@ -171,9 +176,27 @@ dataObject.setSnapshotVersion(dataRow.getVersion()); } - // record id change + // record id change and update attributes for generated ids if (id.isReplacementIdAttached()) { + + Map replacement = id.getReplacementIdMap(); + Iterator idProperties = descriptor.getIdProperties(); + while (idProperties.hasNext()) { + AttributeProperty property = (AttributeProperty) idProperties + .next(); + Object value = replacement.get(property + .getAttribute() + .getDbAttributeName()); + + // TODO: andrus, 11/28/2006: this operation may be redundant + // if the id wasn't generated. We may need to optimize it... + if (value != null) { + property.writePropertyDirectly(object, null, value); + } + } + ObjectId replacementId = id.createReplacementId(); + result.add(new NodeIdChangeOperation(id, replacementId)); // classify replaced permanent ids as "deleted", as Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainUpdateBucket.java URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainUpdateBucket.java?view=diff&rev=480892&r1=480891&r2=480892 ============================================================================== --- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainUpdateBucket.java (original) +++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/DataDomainUpdateBucket.java Thu Nov 30 03:37:16 2006 @@ -35,6 +35,7 @@ import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.map.ObjEntity; import org.apache.cayenne.query.UpdateBatchQuery; +import org.apache.cayenne.reflect.ClassDescriptor; /** * @since 1.2 @@ -53,17 +54,18 @@ for (Iterator i = dbEntities.iterator(); i.hasNext();) { DbEntity dbEntity = (DbEntity) i.next(); - List objEntitiesForDbEntity = (List) objEntitiesByDbEntity.get(dbEntity); + List objEntitiesForDbEntity = (List) descriptorsByDbEntity.get(dbEntity); Map batches = new LinkedHashMap(); for (Iterator j = objEntitiesForDbEntity.iterator(); j.hasNext();) { - ObjEntity entity = (ObjEntity) j.next(); + ClassDescriptor descriptor = (ClassDescriptor) j.next(); + ObjEntity entity = descriptor.getEntity(); diffBuilder.reset(entity, dbEntity); qualifierBuilder.reset(entity, dbEntity); boolean isRootDbEntity = entity.getDbEntity() == dbEntity; - List objects = (List) objectsByEntity.get(entity); + List objects = (List) objectsByDescriptor.get(descriptor); for (Iterator k = objects.iterator(); k.hasNext();) { Persistent o = (Persistent) k.next(); Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/ClassDescriptor.java URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/ClassDescriptor.java?view=diff&rev=480892&r1=480891&r2=480892 ============================================================================== --- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/ClassDescriptor.java (original) +++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/ClassDescriptor.java Thu Nov 30 03:37:16 2006 @@ -98,6 +98,13 @@ Iterator getProperties(); /** + * Returns an iterator over the properties mapped to id columns. + * + * @since 3.0 + */ + Iterator getIdProperties(); + + /** * Passes the visitor to all properties "visit" method, terminating properties walk * through in case one of the properties returns false. Returns true if all visited * properties returned true, false - if one property returned false. Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/LazyClassDescriptorDecorator.java URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/LazyClassDescriptorDecorator.java?view=diff&rev=480892&r1=480891&r2=480892 ============================================================================== --- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/LazyClassDescriptorDecorator.java (original) +++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/LazyClassDescriptorDecorator.java Thu Nov 30 03:37:16 2006 @@ -83,6 +83,11 @@ checkDescriptorInitialized(); return descriptor.getProperties(); } + + public Iterator getIdProperties() { + checkDescriptorInitialized(); + return descriptor.getIdProperties(); + } public Property getProperty(String propertyName) { checkDescriptorInitialized(); Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/PersistentDescriptor.java URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/PersistentDescriptor.java?view=diff&rev=480892&r1=480891&r2=480892 ============================================================================== --- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/PersistentDescriptor.java (original) +++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/PersistentDescriptor.java Thu Nov 30 03:37:16 2006 @@ -18,12 +18,15 @@ ****************************************************************/ package org.apache.cayenne.reflect; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.apache.cayenne.CayenneRuntimeException; import org.apache.cayenne.PersistenceState; +import org.apache.cayenne.map.ObjAttribute; import org.apache.cayenne.map.ObjEntity; import org.apache.commons.collections.IteratorUtils; @@ -49,6 +52,8 @@ protected ObjEntity entity; + protected Collection declaredIdProperties; + /** * Creates a PersistentDescriptor. */ @@ -63,6 +68,19 @@ */ public void addDeclaredProperty(Property property) { declaredProperties.put(property.getName(), property); + + if (property instanceof AttributeProperty) { + ObjAttribute attribute = ((AttributeProperty) property).getAttribute(); + if (attribute.getDbAttributeName() != null + && attribute.getDbAttribute().isPrimaryKey()) { + + if (declaredIdProperties == null) { + declaredIdProperties = new ArrayList(2); + } + + declaredIdProperties.add(property); + } + } } /** @@ -70,7 +88,11 @@ * ClassDescriptor generated from ObjEntity. */ public void removeDeclaredProperty(String propertyName) { - declaredProperties.remove(propertyName); + Object removed = declaredProperties.remove(propertyName); + + if (declaredIdProperties != null && removed != null) { + declaredIdProperties.remove(removed); + } } public void addSubclassDescriptor(ClassDescriptor subclassDescriptor) { @@ -143,6 +165,22 @@ } } + public Iterator getIdProperties() { + + Iterator it = null; + + if (getSuperclassDescriptor() != null) { + it = getSuperclassDescriptor().getIdProperties(); + } + + if (declaredIdProperties != null) { + it = (it != null) ? IteratorUtils.chainedIterator(it, declaredIdProperties + .iterator()) : declaredIdProperties.iterator(); + } + + return it != null ? it : IteratorUtils.EMPTY_ITERATOR; + } + /** * Recursively looks up property descriptor in this class descriptor and all * superclass descriptors. @@ -210,8 +248,7 @@ * Copies object properties from one object to another. Invokes 'shallowCopy' of a * super descriptor and then invokes 'shallowCopy' of each declared property. */ - public void shallowMerge(final Object from, final Object to) - throws PropertyException { + public void shallowMerge(final Object from, final Object to) throws PropertyException { visitProperties(new PropertyVisitor() { Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/pojo/EnhancedPojoDescriptorFactory.java URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/pojo/EnhancedPojoDescriptorFactory.java?view=diff&rev=480892&r1=480891&r2=480892 ============================================================================== --- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/pojo/EnhancedPojoDescriptorFactory.java (original) +++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/reflect/pojo/EnhancedPojoDescriptorFactory.java Thu Nov 30 03:37:16 2006 @@ -18,7 +18,7 @@ ****************************************************************/ package org.apache.cayenne.reflect.pojo; -import java.util.List; +import java.util.Collection; import org.apache.cayenne.map.ObjEntity; import org.apache.cayenne.map.ObjRelationship; @@ -65,7 +65,10 @@ .getTargetEntityName()); String reverseName = relationship.getReverseRelationshipName(); - Accessor accessor = createAccessor(descriptor, relationship.getName(), List.class); + Accessor accessor = createAccessor( + descriptor, + relationship.getName(), + Collection.class); descriptor.addDeclaredProperty(new EnhancedPojoToManyProperty( descriptor, targetDescriptor, Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/access/DataContextEntityWithMeaningfulPKTest.java URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/access/DataContextEntityWithMeaningfulPKTest.java?view=diff&rev=480892&r1=480891&r2=480892 ============================================================================== --- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/access/DataContextEntityWithMeaningfulPKTest.java (original) +++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/access/DataContextEntityWithMeaningfulPKTest.java Thu Nov 30 03:37:16 2006 @@ -23,7 +23,9 @@ import org.apache.art.MeaningfulPKDep; import org.apache.art.MeaningfulPKTest1; +import org.apache.cayenne.DataObjectUtils; import org.apache.cayenne.ObjectId; +import org.apache.cayenne.query.ObjectIdQuery; import org.apache.cayenne.query.SelectQuery; import org.apache.cayenne.unit.CayenneCase; @@ -46,6 +48,21 @@ obj.setPkAttribute(new Integer(1000)); obj.setDescr("aaa-aaa"); ctxt.commitChanges(); + ObjectIdQuery q = new ObjectIdQuery(new ObjectId( + "MeaningfulPKTest1", + MeaningfulPKTest1.PK_ATTRIBUTE_PK_COLUMN, + 1000), true, ObjectIdQuery.CACHE_REFRESH); + assertEquals(1, ctxt.performQuery(q).size()); + } + + public void testGeneratedKey() throws Exception { + MeaningfulPKTest1 obj = (MeaningfulPKTest1) ctxt.newObject("MeaningfulPKTest1"); + obj.setDescr("aaa-aaa"); + ctxt.commitChanges(); + + assertNotNull(obj.getPkAttribute()); + assertSame(obj, DataObjectUtils.objectForPK(ctxt, MeaningfulPKTest1.class, obj + .getPkAttribute())); } public void testChangeKey() throws Exception { Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/reflect/MockClassDescriptor.java URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/reflect/MockClassDescriptor.java?view=diff&rev=480892&r1=480891&r2=480892 ============================================================================== --- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/reflect/MockClassDescriptor.java (original) +++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/reflect/MockClassDescriptor.java Thu Nov 30 03:37:16 2006 @@ -45,6 +45,10 @@ public Iterator getProperties() { return null; } + + public Iterator getIdProperties() { + return null; + } public ClassDescriptor getSubclassDescriptor(Class objectClass) { return this;