function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
dgscarikadgscarika 

Lead & Task Triggers: Self_Reference_From_Trigger

Hi All,

I’m hoping someone can assist with an error that I’m getting. My requirements are the following:

·         I have a field named TAB_Lead_Owner on my lead records. When this field is changed, it needs to be updated to a field of the same name in all open activities for this lead. This is done in a trigger named Update_Tab_Owner_Lead.

·         I also have some custom task fields. When these fields are set to certain values on a task record, they update the Lead Status value on their associated lead record. This is done in a trigger named Update_Tab_Owner_Task.

I’m running into a recursion error. I receive the following error message: First exception on row 0 with id 00T800000119bodEAA; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = 00T800000119bod) is currently in trigger Update_Tab_Owner_Task, therefore it cannot recursively update itself. I think I understand why this error is occurring. Does anyone know a way around it, to prevent bi-directional triggers on records in related lists, from causing this recursion error?  Here is the source for Update_Tab_Owner_Lead: trigger Update_Tab_Owner_Lead on Lead (after update){
        
    if(Trigger.isUpdate){
        if(Trigger.isAfter){
            //if (Trigger.old.size()==1){   
            
                Set<Id> LId = new Set<Id>();
                List<Task> updTask = new List<Task>();
                List<Event> updEvent = new List<Event>();
                
                Set<Id> TaskIds = new Set<Id>();
                Set<Id> EventIds = new Set<Id>();
                                  
                for(Lead oLead : Trigger.new){
                    if(!LId.contains(oLead.Id)){
                        LId.add(oLead.Id);
                    }                
                }
                if(LId!=null&&LId.size()>0){
                
                    //Get Existing Tasks
                    List<Task> exTask =[select Id,TAB_Lead_Owner__c from Task where WhoId in :LId and status != 'Completed'];
                    
                    //Get Existing Events
                    List<Event> exEvent =[select Id,TAB_Lead_Owner__c from Event where WhoId in :LId and EndDateTime>:datetime.now() ];
                    
                    //Loop through all leads in the batch
                    for(Lead oLead : Trigger.new){
                       
                        for(Task tmpTask:exTask){ CODE TO UPDATE TAB_LEAD_OWNER FIELD}
                                                    
                        for(Event tmpEvent:exEvent){ CODE TO UPDATE TAB_LEAD_OWNER FIELD}                         
                    }
                }
                if(updTask.size()>0){
                    update updTask;
                }
                if(updEvent.size()>0){
                    update updEvent;
                }
        }
    }    
}
 

 

Here is the source for Update_Tab_Owner_Task: 

 

trigger Update_Tab_Owner_Task on Task (before update){
    List<Id> whoIds = new List<Id>();
    for(Task oTask : Trigger.new){
        whoIds.add(oTask.WhoId);   
    }

list<Task> lTask = new list<Task>();
    List<lead> leadUpdate = new List<lead>();
    Map<Id,Lead> leadMap = new Map<Id,Lead>();

    for(Lead tmpLead:[select Id,TAB_Lead_Owner__c,Status,Notes__c from lead where Id in:whoIds]){
        leadMap.put(tmpLead.Id,tmpLead);
    }

    for(Task oTask : Trigger.new){
        //Update the Lead if the Prospect Contact=true
        if(leadMap.containsKey(oTask.WhoId)){
            Lead tmpLead = leadMap.Get(oTask.WhoId);
               if(test){
                CODE TO UPDATE TMPLEAD FIELDS

                    leadUpdate.add(tmpLead);
            }           }
    
        if(leadUpdate.size()==100)
        {
             update leadUpdate ;
             leadUpdate.clear();
       }
    }

    if(leadUpdate.size()>0)
    {
         update leadUpdate ;
   }
}
 

Thanks for any help on this! Dave

SteveMTCSteveMTC

Hi Dave

 

One way I've found of stopping recursive trigger firing is to have a class with a global variable set to false. Your trigger will then check this variable is false when it runs, then once it has run, you set it to true, preventing the trigger from running again for that record set.

 

 

Message Edited by SteveMTC on 10-19-2009 08:01 AM
dgscarikadgscarika

Hi Steve,

 

Thank you for taking the time to respond. Before embarking with making this change, I have two follow on questions:

 

  1. We have an Enterprise Edition license. In an EE setting, do SFDC triggers fire individually for each user’s session? That is, by using a global variable, I want to confirm that actions of multiple users operating in our EE environment cannot interfere with each other? 
  2. We run various mass updates on leads. I wanted to confirm that using a global variable will work when leads are being mass updated. As I understand it, since our recursion is caused by a lead trigger updating a field on its open activities and an activity trigger updating fields on its associated lead record, we would want to set/check the global variable in the lead trigger. So, on a mass update, if it fires the triggers in sequence so that calls are not interfering with the global variable setting, this should work. Are you able to confirm?

 

Thanks for any additional help!

Dave