Hi Bilgin:
I'm sure this is a really stupid question, but that has never stopped me
before :-)
I'm wonder how this compiles:
Delegator delegator = dctx.getDelegator();
Shouldn't that be GenericDelegator ? What have I overlooked?
TIA
Ruth
Bilgin Ibryam wrote:
Christopher Snow wrote:
Is it possible to do a cascade delete in an ofbiz service?
Many thanks in advance,
Chris
Hi Chris,
I also have to do cascade deleting data. For this purpose I created a
generic service which accepts the entity name and primary key fields
and delete the entry and all the related data entries.
I tried it with few entities (workeffort, orderheader, invoice) and it
works correct. Could you try it tell us if it worked also for your
case. Here is the patch
Bilgin
Index: framework/common/servicedef/services_test.xml
===================================================================
--- framework/common/servicedef/services_test.xml (revision 909781)
+++ framework/common/servicedef/services_test.xml (working copy)
@@ -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>
Index: framework/common/src/org/ofbiz/common/CommonServices.java
===================================================================
--- framework/common/src/org/ofbiz/common/CommonServices.java
(revision 909781)
+++ framework/common/src/org/ofbiz/common/CommonServices.java
(working copy)
@@ -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,39 @@
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);
+ CommonServices.cascadeDelete(dctx, newContext);
+ }
+ }
+ + Debug.logInfo("Removing value: " + value ,
module);
+ delegator.removeValue(value);
+ } catch (GenericEntityException e) {
+ return ServiceUtil.returnError(e.getMessage());
+ }
+
+ return ServiceUtil.returnSuccess();
+ }
}