Skip to main content

How to ByPass and Apex Triggers and Avoid Loops

How to ByPass and Apex Triggers and Avoid Loops

Sometimes, when developing a trigger from some reasons we need to by pass the a trigger, may, as I mentioned in my previous post "System.LimitException: Too many SOQL queries: 101", sometimes we have loops in our triggers logic. 

In Other occasions we just want to bypass because records were processed previously. Our first approach for bypassing its to execute an SOQL query to see if record need to be processed or use fields in the object.


trigger TriggerTest on User (before insert. before update) {

 //First go to Database 

     Set ids = Trigger.newMap.keySet();

     List relatedObjs  = [SELECT Id,Name FROM relatedObject__c WHERE parent__c in :ids]; 

 //Here check which users need to be processed.

  List UsersToProcess = new List();  

  for(User usr: Trigger.new){ 

   //Use the values on relatedObjs to validate

   UsersToProcess.add(usr);

  }   

 //Process the records

  if(UsersToProcess.size() > 0){

     //Do the process logic, usually a helper class to perform a task   

  }

}  


But due to Salesforce Order of Execution or other conditions like loops in the code, the info from Database might not be recent. In this cases I have seen better results using static class to control the logic, something like:


public class TriggerHelper {

    Private static Set bypassedUsers ;

    public static void generateSet(){
        bypassedUsers = new Set();
        
        //Here you can add more logic, like get some users from a custom object or with an specific detail
    }
    
    public static void addUserToByPass(String UserId){
        
        if (bypassedUsers == null){
            generateSet();
        }
        
        bypassedUsers.add(UserId);
        
    }
    
    public static boolean doesUserNeedToBeByPassed(String UserId){
        if (bypassedUsers == null){
            generateSet();
        }
        
         return bypassedUsers.contains(UserId);       
    }   
    

}


The use this class in the trigger to mark records that were processed, depending on the logic we can use record Id, or any other field that makes sense. (remember that record wont have an Id in a Before Insert trigger, Id will be assigned after all before triggers ran).
trigger TriggerTest on User (before insert, before update) {
    
    List UsersToProcess = new List();
        
    //First check users to process.
    for(User usr: Trigger.new){
         if( !TriggerHelper.doesUserNeedToBeByPassed(usr.UserName) ){
               //Here usually add an if to only add those users that need to be processed.
    UsersToProcess.add(usr);
  }        
    }
    
    //Process users if there is any
    if(UsersToProcess.size() > 0){
        for(User usr: UsersToProcess){
     //Do the process logic, ussually a helper class to perform a task        
            TriggerHelper.addUserToByPass(usr.UserName);
       }
    }

}

This model can be improved to add more complexity, instead of having an static set on the helper class, we could use an static Map and have more complex validations.

Similarly we could modify the class to use the database in order pre-fill some values of records that were already processes. Of course we need to consider the governor limits of salesforce and use the helper class properly (EG: avoid an SOQL with more that 50k records, or the class will fail).






Comments

Popular posts from this blog

Salesforce ListView as a Home Page component.

Display ListView as a Home Page component. In this show an example to use the a pex:enhancedList  VisualForce component in order to display a ListView in a VisualForce Page, and then embed this as a Home Page component. The final result should be something like this: Step 1: Create a ListView I suggest doing this with a ListView, as we left the control of which records list will be filtered to Administrators or End users. First step its to create a list view with the data that you want to show: Step 2: Create a VisualForce Page  Go to  Setup -> Build --> Develop --> Pages --> New. And create a new Page with this sniped of code: The page is using an  enhancedList Visualforce Component, for more details about this component here is the documentation: http://www.salesforce.com/us/developer/docs/pages/index_Left.htm#CSHID=pages_compref_composition.htm|StartTopic=Content%2Fpages_compref_composition.htm|...