Thursday 1 June 2017

Best Solution Of Recursive Trigger Problem!

What is Recursive Trigger?


A recursive trigger is one that performs an action, such as an update or insert, which invokes itself .
Recursion occurs when same block of code executing again and again. It can be lead to infinite loop.
Sometime governor limits may occur. Occurrence of Recursion in Trigger is very common then trigger will show unexpected output or error.

To avoid these kind of situation we can use public class static variable in class and use in trigger code. I will discuss this code later , first lets look on the error scenario when Recursion occurs in trigger. I am attaching some screenshots of error and code that through error. 
Later I solved this problem by static variable. 

1. Errors when recursive trigger exist-- 

I create atfter update trigger on Account object.it takes all the contacts from account object and update the contact mailing Address.
I create another after update trigger on Contact object.it monitor the last contact update.I got recursive error below--


Update perform on Account-

Update perform on Contact-

Code of Triggers On Account and Contacts with Recursive Error--

On Account-

trigger AccountRecursiveTrigger on Account (after insert,after update) 
{
    List<Contact> updateContact=new List<Contact>();
    List<Account> accounts=new List<Account>();
    accounts=[select id,Name,BillingStreet,BillingCity,BillingCountry,
              (select id,FirstName,LastName,MailingStreet,MailingCity,MailingCountry from Contacts) from Account where id IN:trigger.new and BillingStreet!=null];
    system.debug('cc::'+accounts);
    for(Account acc:accounts)
    {
        for(Contact con:acc.Contacts)
        {
            con.MailingStreet=acc.BillingStreet;
             con.MailingCity=acc.BillingCity;
            con.MailingCountry=acc.BillingCountry;
            updateContact.add(con);
            
        }
    }
    update updateContact;    
}

On Contact-

trigger ContactRecursiveTrigger on Contact (after insert,after update) {
    Map<id,Account> updateAccount=new Map<id,Account>();
    for(Contact con:trigger.new){
        if(con.AccountId !=null){
            
            Account acc=new Account(id=con.AccountId,Contact_Last_Updates__c=system.now());
            updateAccount.put(con.AccountId, acc);
        }
    }
    System.debug('valuess:'+updateAccount.values());
    update updateAccount.values();
         
}

If you try to update any object record it will through error shown above.


SOLUTION:-

Now to solve this problem, I create a Class 'RecursiveHandler' which has static variable and it set to true.

public class RecursiveHandler{
     public static Boolean saveRecursive = true;
}

Now use this class variable is any object trigger code either on Account or in Contact. And set the static variable value false so that it will not enter in loop again. It will stop in first execution.

I use in Account object as below:

trigger AccountRecursiveTrigger on Account (after insert,after update) 
{
    List<Contact> updateContact=new List<Contact>();
    List<Account> accounts=new List<Account>();
    accounts=[select id,Name,BillingStreet,BillingCity,BillingCountry,
              (select id,FirstName,LastName,MailingStreet,MailingCity,MailingCountry from Contacts) from Account where id IN:trigger.new and BillingStreet!=null];
    system.debug('cc::'+accounts);
    if(RecursiveHandler.saveRecursive)
    {
        RecursiveHandler.saveRecursive=false;
        for(Account acc:accounts)
        {
            for(Contact con:acc.Contacts)
            {
                
                 con.MailingStreet=acc.BillingStreet;
                 con.MailingCity=acc.BillingCity;
                con.MailingCountry=acc.BillingCountry;
                updateContact.add(con);
                
            }
            
        }
        update updateContact;   
    }
}

Now update record on any object , It will not through error and record will be updated successfully.


0 comments:

Post a Comment

If you have any doubts, please let me know.