Tell me more ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

This is my trygger on Opportunity object.

trigger AutoProductupdate on Opportunity ( before update,after update) {
  static boolean already=false;
  if (already==false){
    for(Opportunity newOppt : Trigger.new){       
      if  (trigger.isAfter){
        if (newOppt.Pricing_Tears__c.trim()=='Gigabyte'){                                   
          SYSTEM.DEBUG('update');

          Automations.UpdateOpportunityLineItems(newOppt);
          //Action of the called function: 
          //DELETE OPPORTUNITY LINE ITEM SCHEDULES FOR ALL THE PRODUCTS
          // UPDATE OPPORTUNITY LINE ITEM
          Automations.SheduleOpportunityLineItem(newOppt);
          //Action of the called function: 
          // CREATE OPPORTUNITY LINE ITEM SCHEDULES FOR ALL THE PRODUCTS
        }
      }  
    }        

    already=true; 
   }                   
}

I am working with opportunity product and opportunity product schedules. In the debug log i see that the trigger is working recursively (It 's printed 15 times the string 'update' with the system.debug).

The error message:

execution of AfterUpdate caused by: System.DmlException: Delete failed. First exception on row 0 with id 00oL0000000acVqIAI; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, AutoProductupdate: maximum trigger depth exceeded Opportunity trigger event AfterUpdate for [006L0000003EUVZ] Opportunity trigger event AfterUpdate for [006L0000003EUVZ] Opportunity trigger event AfterUpdate for [006L0000003EUVZ] Opportunity trigger event AfterUpdate for [006L0000003EUVZ] Opportunity trigger event AfterUpdate for [006L0000003EUVZ] Opportunity trigger event AfterUpdate for [006L0000003EUVZ] Opportunity trigger event AfterUpdate for [006L0000003EUVZ] Opportunity trigger event AfterUpdate for [006L0000003EUVZ] Opportunity trigger event AfterUpdate for [006L0000003EUVZ] Opportunity trigger event AfterUpdate for [006L0000003EUVZ] Opportunity trigger event AfterUpdate for [006L0000003EUVZ] Opportunity trigger event AfterUpdate for [006L0000003EUVZ] Opportunity trigger event AfterUpdate for [006L0000003EUVZ] Opportunity trigger event AfterUpdate for [006L0000003EUVZ] Opportunity trigger event AfterUpdate for [006L0000003EUVZ] Opportunity trigger event AfterUpdate for [006L0000003EUVZ]: []: Class.Automations.UpdateOpportunityLineItems: line 70, column 1

Which is the problem?

How can avoid this?

share|improve this question
2  
have you looked into this salesforce.com/docs/developer/cookbook/Content/… answer is simple use a static variable to control the recursion. –  rao Jul 17 at 17:46
 
Thank you very useful! –  Enry Jul 17 at 20:02
 
@Rao, looks like you should add your solution as the answer. Enry, it is nice to let someone who solves your problem in a comment to add it as an answer so they can get rep. –  Daniel Hoechst Jul 17 at 20:40
 
@DanielHoechst I always try to be on the safe side of adding a link that I did not work on as comment than as an answer to be safe from dreaded downvotes. –  rao Jul 17 at 20:44
 
@rao, so do I, but once the person confirms it is correct, I usually make it an answer. –  Daniel Hoechst Jul 17 at 20:46
show 1 more comment

3 Answers

It looks like your method Automations.UpdateOpportunityLineItems is causing the loop so I would recommend a couple of fixes:

  1. You probably need to set already=true earlier, immediately after the if (already==false) statement. By delaying this assignment to the end you aren't preventing the loop.

  2. Do not allow the called methods to execute DML; instead, provide them with a global static map<Id, sObject> variable for each sObject type. These methods would place the updated records in the global object, which would then be updated at the end.

share|improve this answer

Solution: Use a static variable

in an Apex class

(you mustn't set the static variable in the trigger, create a class) to avoid an infinite loop.

http://www.salesforce.com/docs/developer/cookbook/Content/apex_controlling_recursive_triggers.htm

share|improve this answer
 
There is a hidden problem with this cookbook recipe, it's not properly bulkified, if your trigger is processing more than 200 records, the static variable will have the wrong state when processing the second group of records. I would suggest implementing @MikeChale's solution –  Daniel Blackhall Jul 17 at 21:54
 
Hi Daniel,Thanks for your help.I have tried to use the static variable in the trigger but it doesn't work.Please can you explain your solution?.Thanks a lot –  Enry Jul 18 at 6:22
 
Take a look at Mike Chale's answer, that is how I would do it –  Daniel Blackhall Jul 18 at 22:10

Introducing static variables to control recursion may be a good start, but soon might lead to messy code if you have huge apex codebase to handle your business logic.

There are several design patterns to handle recursive triggers. Check out Dan Appleman's Advanced Apex Programming to see his proposal towards handling recursion. Alternatively, you might want to check my blog post on 'An architecture framework to handle apex triggers in Force.com platform' which solves not only the recursion, but also promotes SOC, clean code structure and control execution order.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.