You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by ar...@apache.org on 2007/10/29 11:23:17 UTC

svn commit: r589575 - /db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java

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 {@link CollectionDescriptor} of the real object
-     * @param referencedObjects the referenced objects ({@link 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 {@link CollectionDescriptor} of the real object
-     * @param referencedObjects the referenced objects ({@link 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 {@link ClassDescriptor} of the real target object
      * @param rds An {@link ObjectReferenceDescriptor} or {@link 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 {@link ClassDescriptor} of the real target object
      * @param rds An {@link ObjectReferenceDescriptor} or {@link 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: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org