4

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?

5
  • 4
    have you looked into this salesforce.com/docs/developer/cookbook/Content/… answer is simple use a static variable to control the recursion.
    – Rao
    Commented Jul 17, 2013 at 17:46
  • @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. Commented Jul 17, 2013 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
    Commented Jul 17, 2013 at 20:44
  • @rao, so do I, but once the person confirms it is correct, I usually make it an answer. Commented Jul 17, 2013 at 20:46
  • @DanielHoechst point taken :),will follow the above advice going forward
    – Rao
    Commented Jul 17, 2013 at 20:53

3 Answers 3

4

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.

0
0

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

3
  • 1
    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 Commented Jul 17, 2013 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
    Commented Jul 18, 2013 at 6:22
  • Take a look at Mike Chale's answer, that is how I would do it Commented Jul 18, 2013 at 22:10
0

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .