You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ofbiz.apache.org by Christopher Snow <sn...@snowconsulting.co.uk> on 2010/02/02 16:54:38 UTC

cascade deletes

Is it possible to do a cascade delete in an ofbiz service?

Many thanks in advance,

Chris

Re: cascade deletes

Posted by Ruth Hoffman <rh...@aesolves.com>.
Hi Bilgin:
Thanks.
Could you maybe explain the reason why this was done?
Ruth

Bilgin Ibryam wrote:
> Ruth Hoffman wrote:
>> 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
>
> Ruth,
>
> there was some refactoring of delagator class in ofbiz trunk 
> introduced few months ago by Adrian.
> Now there is an Delegator interface which should be used instead of 
> the implementing GenericDelegator class.
>
> Bilgin
>

Re: cascade deletes

Posted by Bilgin Ibryam <bi...@gmail.com>.
Ruth Hoffman wrote:
> 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

Ruth,

there was some refactoring of delagator class in ofbiz trunk introduced 
few months ago by Adrian.
Now there is an Delegator interface which should be used instead of the 
implementing GenericDelegator class.

Bilgin

Re: cascade deletes

Posted by Ruth Hoffman <rh...@aesolves.com>.
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();
> +    }  
> }
>
>

Re: cascade deletes

Posted by Bilgin Ibryam <bi...@gmail.com>.
Jens Oechsler wrote:
>  
> Hi
> I tried to use your patch to delete a product and it seemed to loop
> between ProductAttribute and ProductTypeAttr I think.
>   
I made some improvements to it and tried to delete only FK related data, 
but even then it doesn't work correct in some situations. As proposed in 
developer list, you better don't use this patch (or use it on your own 
responsibility)

Bilgin

Re: cascade deletes

Posted by Jens Oechsler <jf...@smart-ebizz.com>.
2010/2/13 Bilgin Ibryam <bi...@gmail.com>:
> 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
>

Hi
I tried to use your patch to delete a product and it seemed to loop
between ProductAttribute and ProductTypeAttr I think.

Re: cascade deletes

Posted by Bilgin Ibryam <bi...@gmail.com>.
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();
+    }   
 
 }