Author: arminw Date: Mon Oct 29 03:23:16 2007 New Revision: 589575 URL: http://svn.apache.org/viewvc?rev=589575&view=rev Log: improve deletion and handling of references on main object store
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java?rev=589575&r1=589574&r2=589575&view=diff ============================================================================== --- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java (original) +++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java Mon Oct 29 03:23:16 2007 @@ -65,8 +65,6 @@ import org.apache.ojb.broker.cache.ObjectCacheFactory; import org.apache.ojb.broker.cache.ObjectCacheInternal; import org.apache.ojb.broker.core.proxy.AbstractProxyFactory; -import org.apache.ojb.broker.core.proxy.CollectionProxy; -import org.apache.ojb.broker.core.proxy.CollectionProxyDefaultImpl; import org.apache.ojb.broker.core.proxy.IndirectionHandler; import org.apache.ojb.broker.core.proxy.ProxyFactory; import org.apache.ojb.broker.core.proxy.VirtualProxy; @@ -87,9 +85,10 @@ import org.apache.ojb.broker.query.QueryBySQL; import org.apache.ojb.broker.util.BrokerHelper; import org.apache.ojb.broker.util.ClassHelper; +import org.apache.ojb.broker.util.IdentityArrayList; import org.apache.ojb.broker.util.IdentityHashSet; import org.apache.ojb.broker.util.ObjectModification; -import org.apache.ojb.broker.util.IdentityArrayList; +import org.apache.ojb.broker.util.collections.IRemovalAwareCollection; import org.apache.ojb.broker.util.configuration.Configuration; import org.apache.ojb.broker.util.configuration.ConfigurationException; import org.apache.ojb.broker.util.logging.Logger; @@ -646,11 +645,11 @@ { // replace specified object with the real one obj = getProxyFactory().getRealObject(obj); - if(cld == null) cld = getClassDescriptor(obj.getClass()); + if(cld == null || cld.isInterface()) cld = getClassDescriptor(obj.getClass()); if(oid == null) oid = serviceIdentity().buildIdentity(cld, obj); // first check for already deleted objects (cirluar object graph) - if (nowDeleting.contains(obj) || deletedDuringTransaction.contains(oid)) + if (obj == null || nowDeleting.contains(obj) || deletedDuringTransaction.contains(oid)) { return; } @@ -661,7 +660,7 @@ if (oid.isTransient()) { String msg = "Can't delete transient (already deleted?) object: " + obj; - logger.error(msg); + logger.warn(msg); return; } @@ -850,7 +849,7 @@ { if(rds.isSuperReferenceDescriptor()) { - ClassDescriptor base = cld.getSuperClassDescriptor(); + ClassDescriptor base = rds.getItemClassDescriptor(); /* arminw: If "table-per-subclass" inheritance is used we have to guarantee that all super-class table entries are deleted too. @@ -1083,7 +1082,7 @@ // get all members of obj that are references and store them Collection listRds = cld.getObjectReferenceDescriptors(); // return if nothing to do - if(listRds == null || listRds.size() == 0) + if(listRds == null || listRds.isEmpty()) { return; } @@ -1168,22 +1167,48 @@ // if CASCADE_NONE was set, do nothing with referenced objects if (!cod.isCascadingStoreNone()) { - Object referencedObjects = cod.getPersistentField().get(obj); + CollectionContainer container = new CollectionContainer(this, cod, obj); if (cod.isMtoNRelation()) { - storeAndLinkMtoN(false, obj, cod, referencedObjects, insert); + storeAndLinkMtoN(false, container, insert); } else { - storeAndLinkOneToMany(false, obj, cod, referencedObjects, insert); + storeAndLinkOneToMany(false, container, insert); } // BRJ: only when auto-update is 'object' (CASCADE_OBJECT) // or with CASCADE_CREATE - if ((referencedObjects instanceof ManageableCollection) - && (cod.isCascadingStoreObject() || cod.isCascadingStoreCreate())) + if (container.isManageableCollection()) + { + if((cod.isCascadingStoreObject() || cod.isCascadingStoreCreate()) + && !container.isUnmaterializedProxy()) + { + ((ManageableCollection) container.getReference()).afterStore(this); + } + } + // If a removal aware collection is used, replace the collection instance + // if it doesn't match IRemovalAwareCollection + else { - ((ManageableCollection) referencedObjects).afterStore(this); + if(!cod.isArrayType() && container.isCollection()) + { + if(IRemovalAwareCollection.class.isAssignableFrom(getCollectionTypes().getCollectionClass(cod))) + { + ManageableCollection refCollection = getCollectionTypes().createCollectionClass(cod); + if(IRemovalAwareCollection.class.isAssignableFrom(refCollection.getClass())) + { + // replace collection type with OJB's collection type to enable + // OJB's tracking collection features + Iterator it = ((Collection) container.getReference()).iterator(); + while(it.hasNext()) + { + refCollection.ojbAdd(it.next()); + } + cod.getPersistentField().set(obj, refCollection); + } + } + } } } } @@ -1192,13 +1217,10 @@ /** * Store/Link m:n collection references. * - * @param obj real object the reference starts - * @param cod [EMAIL PROTECTED] CollectionDescriptor} of the real object - * @param referencedObjects the referenced objects ([EMAIL PROTECTED] ManageableCollection} or Collection or Array) or null + * @param container The reference container object. * @param insert flag for insert operation */ - private void storeAndLinkMtoN(boolean onlyLink, Object obj, CollectionDescriptor cod, - Object referencedObjects, boolean insert) + private void storeAndLinkMtoN(boolean onlyLink, CollectionContainer container, boolean insert) { /* - if the collection is a collectionproxy and it's not already loaded @@ -1206,14 +1228,10 @@ - on insert we link and insert the referenced objects, because the proxy collection maybe "inherited" from the object before the PK was replaced */ - if(insert || !(referencedObjects instanceof CollectionProxy - && !((CollectionProxy) referencedObjects).isLoaded())) + if(insert || !container.isUnmaterializedProxy()) { // if referenced objects are null, assign empty list - if(referencedObjects == null) - { - referencedObjects = Collections.EMPTY_LIST; - } + /* NOTE: Take care of referenced objects, they could be of type Collection or an Array or of type ManageableCollection, thus it is not guaranteed that we @@ -1224,10 +1242,11 @@ */ Iterator referencedObjectsIterator; - boolean cascadingStoreCreate = cod.isCascadingStoreCreate(); - if(!onlyLink && (cascadingStoreCreate || cod.isCascadingStoreObject())) + boolean cascadingStoreCreate = container.getDescriptor().isCascadingStoreCreate(); + if(!onlyLink && !container.isNullReference() + && (cascadingStoreCreate || container.getDescriptor().isCascadingStoreObject())) { - referencedObjectsIterator = BrokerHelper.getCollectionIterator(referencedObjects); + referencedObjectsIterator = BrokerHelper.getCollectionIterator(container.getReference()); while (referencedObjectsIterator.hasNext()) { Object refObj = referencedObjectsIterator.next(); @@ -1241,42 +1260,38 @@ } } } - mtoNBroker.storeMtoN(obj, cod, referencedObjects, insert); + mtoNBroker.storeMtoN(container.getSource(), + container.getDescriptor(), + container.isNullReference() ? Collections.EMPTY_LIST : container.getReference(), + insert); } } /** * Store/Link 1:n collection references. * - * @param obj real object the reference starts * @param linkOnly if true the referenced objects will only be linked (FK set, no reference store). * Reference store setting in descriptor will be ignored in this case - * @param cod [EMAIL PROTECTED] CollectionDescriptor} of the real object - * @param referencedObjects the referenced objects ([EMAIL PROTECTED] ManageableCollection} or Collection or Array) or null + * @param container The reference container object. * @param insert flag for insert operation */ - public void storeAndLinkOneToMany(boolean linkOnly, Object obj, CollectionDescriptor cod, - Object referencedObjects, boolean insert) + public void storeAndLinkOneToMany(boolean linkOnly, CollectionContainer container, boolean insert) { - if(referencedObjects == null) - { - return; - } /* Only make sense to perform (link or/and store) real referenced objects or materialized collection proxy objects, because on unmaterialized collection nothing has changed. - - if the collection is a collectionproxy and it's not already loaded no need to perform an update on the referenced objects - on insert we link and insert the referenced objects, because the proxy collection maybe "inherited" from the object before the PK was replaced */ - if(insert || !(referencedObjects instanceof CollectionProxy - && !((CollectionProxy) referencedObjects).isLoaded())) + if(!container.isNullReference() && (insert || !container.isUnmaterializedProxy())) { - Iterator it = BrokerHelper.getCollectionIterator(referencedObjects); + Iterator it = BrokerHelper.getCollectionIterator(container.getReference()); Object refObj; + CollectionDescriptor cod = container.getDescriptor(); + Object source = container.getSource(); while(it.hasNext()) { refObj = it.next(); @@ -1295,7 +1310,7 @@ ClassDescriptor refCld = getClassDescriptor(getProxyFactory().getRealClass(refObj)); // get the real object before linking refObj = getProxyFactory().getRealObject(refObj); - link(refObj, refCld, cod, obj, insert); + link(refObj, refCld, cod, source, insert); // if enabled cascade store or store on insert, store the referenced objects if(!linkOnly) { @@ -1314,23 +1329,23 @@ } /** - * Assign FK value to target object by reading PK values of referenced object. + * Assign FK value to target object by reading PK values of the source object. * * @param targetObject real (non-proxy) target object * @param cld [EMAIL PROTECTED] ClassDescriptor} of the real target object * @param rds An [EMAIL PROTECTED] ObjectReferenceDescriptor} or [EMAIL PROTECTED] CollectionDescriptor} * associated with the real object. - * @param referencedObject referenced object or proxy + * @param source the source object * @param insert Show if "linking" is done while insert or update. */ - public void link(Object targetObject, ClassDescriptor cld, ObjectReferenceDescriptor rds, Object referencedObject, boolean insert) + public void link(Object targetObject, ClassDescriptor cld, ObjectReferenceDescriptor rds, Object source, boolean insert) { // MBAIRD: we have 'disassociated' this object from the referenced object, // the object represented by the reference descriptor is now null, so set // the fk in the target object to null. // arminw: if an insert was done and ref object was null, we should allow // to pass FK fields of main object (maybe only the FK fields are set) - if (referencedObject == null) + if (source == null) { /* arminw: @@ -1345,7 +1360,7 @@ } else { - setFKField(targetObject, cld, rds, referencedObject); + setFKField(targetObject, cld, rds, source); } } @@ -1363,15 +1378,15 @@ } /** - * Set the FK value on the target object, extracted from the referenced object. If the referenced object was + * Set the FK value on the target object, extracted from the source object. If the source object is * <i>null</i> the FK values were set to <i>null</i>, expect when the FK field was declared as PK. * * @param targetObject real (non-proxy) target object * @param cld [EMAIL PROTECTED] ClassDescriptor} of the real target object * @param rds An [EMAIL PROTECTED] ObjectReferenceDescriptor} or [EMAIL PROTECTED] CollectionDescriptor} - * @param referencedObject The referenced object or <i>null</i> + * @param source The source object or <i>null</i> */ - private void setFKField(Object targetObject, ClassDescriptor cld, ObjectReferenceDescriptor rds, Object referencedObject) + private void setFKField(Object targetObject, ClassDescriptor cld, ObjectReferenceDescriptor rds, Object source) { ValueContainer[] refPkValues; FieldDescriptor fld; @@ -1380,16 +1395,13 @@ { throw new PersistenceBrokerException("No foreign key fields defined for class '"+cld.getClassNameOfObject()+"'"); } - if(referencedObject == null) + if(source == null) { refPkValues = null; } else { -// Class refClass = proxyFactory.getRealClass(referencedObject); -// ClassDescriptor refCld = getClassDescriptor(refClass); -// refPkValues = brokerHelper.getKeyValues(refCld, referencedObject, false); - refPkValues = brokerHelper.getFkTargetValuesForObject(rds, referencedObject, false); + refPkValues = brokerHelper.getFkTargetValuesForObject(rds, source, false); } for (int i = 0; i < objFkFields.length; i++) { --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]