2

I have below trigger code getting -

DML Exception 'Maximum Trigger Depth Exceeded'.

Can someone help me please?

Apex Trigger

trigger updateAoC on Contract_vod__c(after update) {  
    List<Contract_vod__c> contracts= new List<Contract_vod__c>();
    String Uid = UserInfo.getUserId();
    for (Contract_vod__c c : trigger.new) {
       Contract_vod__c s= new Contract_vod__c(Id=c.Id);
       if(c.AoC_Status_abv__c=='Completed_Electronic')
       s.Completed_By_abv__c=Id.valueof(Uid);
        contracts.add(s);
    }

    if (contracts.isEmpty() == false) {
    update contracts;
    }
}

4 Answers 4

3

Issue here. whenever we update the same object in trigger then always use before update/before insert.

If you want to update other object records (not trigger object) then use after context.

In your case. You are updating same object in after context. So it is firing the trigger again and again. And finally it stuck in a loop that's why you are getting

Maximum Trigger Depth Exceeded error.

Just use before update context and try to update field. This way you don't have to perform DML because you are modifying the data before committing to database.

Check: Triggers and Order of Execution

trigger updateAoC on Contract_vod__c(before update) {  

    String Uid = UserInfo.getUserId();
    for (Contract_vod__c c : trigger.new) {

       if(c.AoC_Status_abv__c=='Completed_Electronic'){
       s.Completed_By_abv__c=Id.valueof(Uid);
       }
    }
}

Updates

Trigger

trigger updateAoC on Contract_vod__c(after update) {  

    updateContract handler = new updateContract();

    if(Trigger.isUpdate && Trigger.isAfter && updateContract.isUpdate)
    {
        updateContract.isUpdate = false;
        handler.onAfterUpdate(Trigger.new);
    }
}

Handler

public class updateContract{

    public static Boolean isUpdate = true;
    public void onAfterUpdate(List<Contract_vod__c> lstContract_vod)
    {
        List<Contract_vod__c> contracts= new List<Contract_vod__c>();
        String Uid = UserInfo.getUserId();
        for (Contract_vod__c c : trigger.new) {
           Contract_vod__c s= new Contract_vod__c(Id=c.Id);
           if(c.AoC_Status_abv__c=='Completed_Electronic')
           s.Completed_By_abv__c=Id.valueof(Uid);
            contracts.add(s);
        }
        update contracts;
        updateContract.isUpdate = true;
    }
}
3
  • Before will cause issue because the AoC_Status_abv__c field value change reflects only after database commit. Apr 1, 2016 at 9:28
  • @SFDC_Learner is it then you need to handle recursive call .. check my post salesforce.stackexchange.com/questions/115767/… to handle recursive call
    – Ratan Paul
    Apr 1, 2016 at 9:31
  • @SFDC_Learner check my updates..
    – Ratan Paul
    Apr 1, 2016 at 9:35
1

While updating the same object on which trigger has been written, we should use Before event. And also, I think there is no need to add the list of contracts to List contracts and then updating the List. Try removing the lines --

8.contracts.add(s); and 

11. if (contracts.isEmpty() == false) {
    update contracts;
    }
1

Given a choice between Apex and just about anything else, Apex will typically be more complex, making it more expensive/confusing/frustrating to build and maintain. In addition to development, it adds time to your testing cycle, because you have to write out automated unit tests and run them frequently. As a good developer, your goal should be to use as little code as possible. It is the last tool you should pull from your toolbox.

In this particular case, you can just replace your trigger with a Workflow Rule and Field Updates. You haven't described any criteria, but the Field Updates would look like:


  • Object: Contract
  • Field: Completed By
  • Value: $User.Id

  • Object: Contract
  • Field: AoC Status
  • Value: "Completed_Electronic"
0

This is a recursion error. To be precise it happens here:

if(c.AoC_Status_abv__c=='Completed_Electronic')
s.Completed_By_abv__c=Id.valueof(Uid);
contracts.add(s);

Compiler will treat this as:

if(c.AoC_Status_abv__c=='Completed_Electronic') {
    s.Completed_By_abv__c=Id.valueof(Uid);
}
contracts.add(s);

So you are actually adding all your records from your Trigger.new to this list and then you check if it's not empty and update it if it isn't.

Then the update of these records will fire that after update trigger again and again and again and so on.

And even if you put the contracts.add(s); in the if block, this will still happen, unless your AoC_Status_abv__c is changed:
update of the new records will fire this trigger again and if AoC_Status_abv__c is still the same, the same records will fire this trigger again and again and again...

You must log in to answer this question.

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