Adrian Crum wrote:
Adam Heath wrote:
[email protected] wrote:
Author: bibryam
Date: Mon Feb 15 15:14:32 2010
New Revision: 910235

URL: http://svn.apache.org/viewvc?rev=910235&view=rev
Log:
Added a generic cascadeDelete service which can be used for data deletion. It uses recursion to delete all the related data entries.

Modified:
    ofbiz/trunk/framework/common/servicedef/services_test.xml
ofbiz/trunk/framework/common/src/org/ofbiz/common/CommonServices.java

Modified: ofbiz/trunk/framework/common/servicedef/services_test.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/servicedef/services_test.xml?rev=910235&r1=910234&r2=910235&view=diff ============================================================================== --- ofbiz/trunk/framework/common/servicedef/services_test.xml (original) +++ ofbiz/trunk/framework/common/servicedef/services_test.xml Mon Feb 15 15:14:32 2010
@@ -210,4 +210,11 @@
         <description>Test Ping Service</description>
<attribute name="message" type="String" mode="INOUT" optional="true"/>
     </service>
+
+    <service name="cascadeDelete" engine="java"
+ location="org.ofbiz.common.CommonServices" invoke="cascadeDelete"> + <description>Remove generic value and its related values</description>
+        <attribute name="entityName" type="String" mode="IN"/>
+        <attribute name="pkFields" type="Map" mode="IN"/>
+    </service>     </services>

Modified: ofbiz/trunk/framework/common/src/org/ofbiz/common/CommonServices.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/src/org/ofbiz/common/CommonServices.java?rev=910235&r1=910234&r2=910235&view=diff ============================================================================== --- ofbiz/trunk/framework/common/src/org/ofbiz/common/CommonServices.java (original) +++ ofbiz/trunk/framework/common/src/org/ofbiz/common/CommonServices.java Mon Feb 15 15:14:32 2010
@@ -45,6 +45,7 @@
 import org.apache.log4j.Logger;
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.UtilDateTime;
+import org.ofbiz.base.util.UtilGenerics;
 import org.ofbiz.base.util.UtilValidate;
import static org.ofbiz.base.util.UtilGenerics.checkList;
@@ -54,6 +55,8 @@
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.model.ModelEntity;
+import org.ofbiz.entity.model.ModelRelation;
+import org.ofbiz.entity.model.ModelViewEntity;
 import org.ofbiz.entity.transaction.TransactionUtil;
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.GenericServiceException;
@@ -534,5 +537,42 @@
return ServiceUtil.returnError("Invalid count returned from database");
         }
     }
+ + public static Map<String, Object> cascadeDelete(DispatchContext dctx, Map<String, Object> context) {
+        Delegator delegator = dctx.getDelegator();
+        String entityName = (String) context.get("entityName");
+ Map<String, Object> pkFields = UtilGenerics.checkMap(context.get("pkFields"));
+        +        try {
+ GenericValue value = delegator.findByPrimaryKey(entityName, pkFields); + ModelEntity modelEntity = delegator.getModelEntity(entityName); + List<ModelRelation> relations = modelEntity.getRelationsManyList(); + + if (value == null || modelEntity instanceof ModelViewEntity) { + return ServiceUtil.returnSuccess();
+            }
+            +            for (ModelRelation relation : relations) {
+                String combinedName = relation.getCombinedName();
+ List<GenericValue> relatedValues = value.getRelated(combinedName);
+                for (GenericValue relatedValue : relatedValues) {
+ pkFields = relatedValue.getPrimaryKey().getAllFields();
+                    entityName = relatedValue.getEntityName();
+ Map<String, Object> newContext = UtilMisc.toMap("entityName", entityName, "pkFields", pkFields); + Map<String, Object>result = CommonServices.cascadeDelete(dctx, newContext);
+                    if (ServiceUtil.isError(result)) {
+                        return result;
+                    }
+                }
+            }
+
+            Debug.logInfo("Removing value: " + value , module);
+            delegator.removeValue(value);
+        } catch (GenericEntityException e) {
+            return ServiceUtil.returnError(e.getMessage());
+        }
+ +        return ServiceUtil.returnSuccess();
+ } }

No, don't do this.  This is very bad.

UserLogin->Party->Person->PartyContactMech->ContactMechType->ContactMech(all)->PartyContactMech(all)->Party(all)

You could end up removing everything from the database so easily.
Please remove this service, it's too dangerous.

I agree. This type of thing has been deliberately left out of the project for that reason.

Thanks for your review guys, I appreciate that. I agree that it is dangerous(as ant clean-all ;) and I was not sure to commit it or not. But I'm just curious how can this service end up removing everything from the database? Also the example you gave is not correct because the service would delete only the ContactMech of the given party, not all the ContactMechs, so then not all the Parties.

I was planning to use this service in deleteWorkEffort service which uses hard coded values for removing related entities, and it doesn't work correct because some of the related entities are not deleted.


Reply via email to