You need to sign in to do that
Don't have an account?
SFDummy
How to prevent object deletion using trigger
I have multiple related objects associated to Product2 (Accounts and MycustomObj__c)
When I am deleting product I am checking if there is any (related lists)
but I do not know who to prevent deletion if I find related list items.
My conditions are when I mass delete products
if there are related items associated to product set the product to inactive do not delete (I do not know how to do this part)
If not related items delete product and all child objects. ( this works fine)
Any suggestions please?
Thanks
Here is a trigger I use to check for children on a custom object and prevent delete if a child exists. It uses sets for ID's which are created earlier in the trigger so you will have to adjust to meet you needs.
Thanks for the prompt response
what is the event that cause the trigger, my event is actual delete itself
step 4 is what I do not know how to do... I am already in delete trigger so product gets deleted
when I print the following it is zero 0
if(!prodIds.isEmpty() || prodIds.size() != 0)
how to prevent deletion .....
Thanks
How are you doing the mass delete? is it via a standard mass delete functionality or a custom written one?
I am doing this in a before Delete trigger...
This is the part that prevents the object from being delete and will continue with the rest of the records and delete if appropriate.
I have to do other processing so I created another class that does that. So I pass Ids to that class
productTriggerHandler.OnBeforeDeleteProdsProcess(prodIds)
@starz26
Does addError will display on screen. I do not want error message on UI when I doing mass delete
does addError work for list looks like it work for only sObject? or should I delete individually..... (I will hit limits)
I will try, thanks clarification
I have not tested it with anything with mass delete yet other than excel connector. Since the mass delete in the UI is not for Opportunity records or custom objects.....
The trigger is actually on the Opportunity and not the account. You did bring up an issue now as I can delete the account and it deletes the opportunity as well even though it should not. Need to add this trigger to account now.
As for single records, yes it add a message to the ui. For the test class, it adds them to the debug logs....
I tried the following just to check if it works
I get the following error in UI
I still do not know how to prevent deletion using trigger when I bulkify my trigger.
ProductsTriggers: execution of BeforeDelete
caused by: System.FinalException: SObject row does not allow errors
Trigger.ProductsTriggers: line 45, column 1
For(Product2__c p : trigger.old){
p.addError('test')
}
This will add an error for all record without checking conditions but should answer your question
changed the code
if(Trigger.isDelete && Trigger.isBefore){
for(Product2 allProdIds:trigger.old){
allProdIds.addError('test');
}
same error
ProductsTriggers: execution of BeforeDelete
caused by: System.FinalException: SObject row does not allow errors
Trigger.ProductsTriggers: line 46, column 1
Need full code for context. What is Product2 a costom object or a variable?
The for loop needs to be using the object for which the trigger was running on i.e:
for(Account a : trigger.old) or for (CustomObject__c c :trigger.old)
Sorry, but just coming into this after seeing it posted to the DF portal.
I feel like I'm missing some information after having read through this thread.
First, what is the action that invokes the trigger? Is it your own code? Is it someone elses? Is it API?
Is the trigger caused by a delete occurring on the Product2 object in the first place? Or is the delete originated from some other object?
In your pseudocode example earlier you list a step: "1. collect all productIDS". I don't understand what you mean by the verb "collect"? Is it a query? Are you pulling out some of the product IDs and not others? And why do you use this step. You already have them in Trigger.oldMap.keyset();.
Finally, I agree with Starz26, without more of your code and more context I don't know how much more help we can be.
That being said, there are a few things I can glean from this conversation. You say you are passing a list of IDs to a helper method. ID data type is considered "primitive" (even though it is not by other prog language standards), but importantly this means it is passed by value. If you simply pass a list of IDs to a helper method, unless you pass something back to the calling context (like a new list of IDs that you should take/not take action on), there is no way for you to prevent deletion from that helper. Try passing the list of sObjects instead. This will pass by reference and then you might be able to use your addError() to prevent delete.
In playing with this scenario in my own org, I found that calling sObject.addError('my message') from within anonymous block gave me the same error. But if I put it into a trigger context, it worked find. So don't know what is going on with you in that one...
Attached the complete code. I am actually mass deleting product2 rows
I have Accounts as related list on Product2. Product2 has Lookup relation to product_Rate__c
Delete action invokes trigger. I create tigger on product2
trigger ProductsTriggers on Product2 (after update, before delete)
in the triggger find product2 that has accounts related list - do not delete product2
(3) find all product_rate__c for product2 and delete (delete product2 and product_rate__C
I am deleting primarily using dataloader.
I'm guessing that there's a missing
somewhere in the code.
The reason you're getting the "SObject row does not allow errors" is because you can only add an error to the object that is a part of the Trigger context, so when you do this:
it works because you're iterating through trigger.old.
However, later on (presumably line 46) you have this:
Which will not work, because "p" is not a part of the trigger context.
You should be able to do this, however:
Here's my re-write of the code you've provided:
the above line give the following error
ProductsTriggers: execution of BeforeDelete
caused by: System.NullPointerException: Attempt to de-reference a null object
Trigger.ProductsTriggers: line 39, column 1
Thanks much in taking time to re-write my code.
But, I am still getting errors when I try to delete product that has account associated.
Delete 1 product with not account association - works (prevent deletion)
Delete 1 prouduct with no account association - works (delete product and product_rate__C associated)
when I try to delete 2 product with one each froma above scenarios I get errors
When I delete combination products, I do not want data loader to error out on all. Is there any way to ignore errors and continue with deletion . I only test with 3 rows. 1 has accoutn association. I got same error on all prorducts.
A bit more careful of a rewrite. Realized there was no point in re-querying products with the ids we gathered from the accounts that are linked to those products - we already have the id, so that should be all we need.
I'm not sure why, but using:
just strikes me as a possible problem, but I can't put my finger on why... so I just skipped that and build a new set in the above. See if that works any better.
Adding the above line prevented Nullpointer exception
Thanks everyone for helping me figure out the problem.
here is the problem statement again
Our system has products (product2) with related objects Account (account) and ProductRate(Product_Rate__c)
When I delete products
if product2account relation exists do not delete
if product2ProductReates exists and no product2account relation delete productRate also
Here is the final code that works both via UI delete and Mass delete.
works well now I am almost done with my test class. Thanks again to all for helping me find the solution