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?

  • 4
    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 '13 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. – Daniel Hoechst Jul 17 '13 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 '13 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 '13 at 20:46
  • @DanielHoechst point taken :),will follow the above advice going forward – Rao Jul 17 '13 at 20:53
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

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

  • 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 – Daniel Blackhall Jul 17 '13 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 '13 at 6:22
  • Take a look at Mike Chale's answer, that is how I would do it – Daniel Blackhall Jul 18 '13 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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