Sunday, 22 May 2011

Writing Apex Trigger : Order of Execution ( Structure your trigger )

Hi All,

In this post we will discuss how does a trigger gets executed. This is very important to know to structure the trigger when there are many triggers on a sObject Type. Lets take a example of a simple class with a static varibale triggerEntryCount
public class Constants
    {
         //Constant to keep track of entry in trigger
         public static Integer triggerEntryCount = 0;
        
    }

A trigger is written
trigger Test_TriggerEntry on Account ( after update , after insert , before insert , 
before update , after delete , before delete ) 
    {
        Constants.triggerEntryCount = Constants.triggerEntryCount + 1;
    }

Now we will write a test class
private static testmethod void testTriggerEntry()
            {
                
                List<Account> listAccInsert =  new List<Account>();
                
                Account a = New Account(Name = 'TestAccountA');
                listAccInsert.add(a);
                Account b = New Account(Name = 'TestAccountB');
                listAccInsert.add(b);
                // insert list of accounts
                insert listAccInsert;
                system.debug('Trigger Entry Count : '+ Constants.triggerEntryCount); 
                
            } 

When we run the test class, system debug shows

Trigger Entry Count : 2
In this trigger entries were made for before insert and after insert.
Sequence for entry : before insert and after insert

Now we change test class a bit to check upsert event where two records are updated and one is inserted
private static testmethod void testTriggerEntry()
            {
                
                List&lt;Account&gt; listAccInsert =  new List&lt;Account&gt;();
                
                Account a = New Account(Name = 'TestAccountA');
                listAccInsert.add(a);
                Account b = New Account(Name = 'TestAccountB');
                listAccInsert.add(b);
                // insert list of accounts
                insert listAccInsert;
                

                //Initialize triger count to zero
                Constants.triggerEntryCount = 0;
                Contact c = new Contact( LastName = ' Test Contat ' , AccountId = a.id , Email =   
                'testTrigger@testMethod.com');
                insert c;
                
                System.debug(' ******** Start Debug ********* ');
                
                List<Account> listAccUpsert =  new List<Account>();
                a.Name = 'New Test Account A';
                b.Name = 'New Test Account B';
                listAccUpsert.add(a);
                listAccUpsert.add(b);
                
                Account a1 = New Account(Name = 'TestAccount');
                listAccUpsert.add(a1);

                //upsert list of accounts
                upsert listAccUpsert;
                system.debug('Trigger Entry Count : '+ Constants.triggerEntryCount);
                
            }
This time in system debug :
Trigger Entry Count : 4
Sequence for entry : Before Insert , After Insert , Before Update , After Update

Now if we have triggers on a sObject for all of these events in that case we need to structure our code in a way that only appropriate code gets executed in a trigger entry.

Structure trigger like this :
trigger Test_Trigger on Account ( after update , after insert , before insert , 
before update , after delete , before delete ) 
    {
        
        if (Trigger.isBefore)
            {
               
                if (Trigger.isInsert)
                    {     
                        // Logic to be executed for Before Insert
                    }
                    
                if (Trigger.isupdate)
                    {   
                        // Logic to be executed for Before Update
                    }
                 
                 if (Trigger.isDelete)
                    {     
                        // Logic to be executed for Before Delete  
                    }
            }
            
        if (Trigger.isAfter)
            {
           
                if (Trigger.isInsert)
                    {     
                        // Logic to be executed for After Insert
                    }
                    
                if (Trigger.isupdate)
                    {   
                        // Logic to be executed for After Update  
                    }
                
                 if (Trigger.isDelete)
                    {     
                        // Logic to be executed for After Delete
                    }
            }    
            
        
    }

In case you have same trigger logic for more then one trigger context
1)Use trigger context variables with logical operator OR ( "||" )
Or
2)Create a method for the logic and use that in the all the contexts where you want it to execute

Regards

2 comments:

Tweet