+ Start a Discussion
Ram Srivastav 7Ram Srivastav 7 

Apex Trigger Firing Twice - How to Prevent?

Hi,

I have defined Apex triggers on after insert which will fire the email on per case basis. Issue is same email is firing twice. Could any one help to get it solve..

trigger sendEmail on Case (after insert,after update) {
    Public static Boolean InitialEmail =false;
  
     for(Case c:trigger.new) {
       
        system.debug('outside'+c.Send_Email_to_Contact__c);
       
        if ((trigger.isInsert || (trigger.oldMap.get(c.Id).Send_Email_to_Contact__c != c.Send_Email_to_Contact__c)) && (c.Send_Email_to_Contact__c && !c.Do_not_Send_Email__c  && c.Email_of_Complainant__c!=null && c.Status!='Completed')) {
               
                system.debug('??????'+c.Send_Email_to_Contact__c);
              
                    sendEmailMessage(c.id,c.ownerId,c.Internal_Comments__c,c.Email_of_Complainant__c,c.Site_Details__c,c.CaseNumber,c.Case_Customer_Reference__c );
        }
       
}       
       
       
KaranrajKaranraj
Hi Ram - You can able to avoid recursive call trigger with the help of static variable.
Check this knowledge article http://help.salesforce.com/apex/HTViewSolution?id=000133752&language=en_US (http://help.salesforce.com/apex/HTViewSolution?id=000133752&language=en_US)

Trigger 
trigger sendEmail on Case (after insert,after update) {
   Public static Boolean InitialEmail =false;
  if(checkRecursive.runOnce())
    {
     for(Case c:trigger.new) {
       
        system.debug('outside'+c.Send_Email_to_Contact__c);
       
        if ((trigger.isInsert || (trigger.oldMap.get(c.Id).Send_Email_to_Contact__c != c.Send_Email_to_Contact__c)) && (c.Send_Email_to_Contact__c && !c.Do_not_Send_Email__c  && c.Email_of_Complainant__c!=null && c.Status!='Completed')) {
               
              system.debug('??????'+c.Send_Email_to_Contact__c);
              
              sendEmailMessage(c.id,c.ownerId,c.Internal_Comments__c,c.Email_of_Complainant__c,c.Site_Details__c,c.CaseNumber,c.Case_Customer_Reference__c );
        }
    }
}       


Class:
public Class checkRecursive{
    private static boolean run = true;
    public static boolean runOnce(){
    if(run){
     run=false;
     return true;
    }else{
        return run;
    }
    }
}


Prem_PalPrem_Pal
Yes Ram. A static variable will help you in this case.

However, it would be better if you could investigate and analyze code to check why the Case is updated twice. :)
kaustav goswamikaustav goswami
Can you please check something.

If you have workflows on the case object and some of those workflows have field updates associated with them then check - if the reavulate workflow rules after field change is checked or not.

What this does is - because of the field update another round of evaluation and subsequent updates take place. Many a times this causes the trigger to fire for the second time.

Let me know if you have further questions.

Thanks,
Kaustav
Ram SrivastavRam Srivastav
Hi KaranrajKaranraj,

Thanks for the update, But my issue is still not yet solve. its throwing error as "Only top-level class variables can be declared static at line 20 column 28".
Even i perform the basic debugging but still the issue is same only.
Would like to back hear from you.
Ram SrivastavRam Srivastav
Hi kaustav goswami,

Yes, I do have workflow for the same but it is in "Inactive mode" so at a time  I am only using Apex Trigger code only.
The issue is its firing the sam email twice.
KaranrajKaranraj
Hi Ram - I think you created class in the same trigger itself, you have to create apex class and trigger separately
Ram SrivastavRam Srivastav
Hi Karanraj,

Heartly thanks to you... Finally my issue is solved.

Regards,
Ram Srivastav
KaranrajKaranraj
Hi Ram – Glad to know, your issue is resolved. Can you close this thread by marking best answer. It will be helpful in future for some one. Thanks, Karan
Ram SrivastavRam Srivastav
Best Answer @Karanraj bro  :):)
Ram Srivastav 7Ram Srivastav 7
Hi, I have defined one trigger which used to intimate the user with acknowledgement mail. To prevent the same email twice i  do have defined one apex class. Issue is my test class is containing just 52% code coverage due to which i am not able to deply my code change into the production. Please help

Apex class code snippet: Code coverage 100%

public Class checkRecursive{
    private static boolean run = true;
    public static boolean runOnce(){
    if(run){
     run=false;
     return true;
    }else{
        return run;
    }
    }
}

Apex Trigger code snippet:

trigger sendEmail on Case (after insert,after update) {
   Public static Boolean InitialEmail =false;
   Public static Boolean FinalEmail =false;

  if(checkRecursive.runOnce()){
   
     for(Case c:trigger.new) {
   
      system.debug('outside'+c.Send_Email_to_Contact__c);
   
       if ((trigger.isInsert || (trigger.oldMap.get(c.Id).Send_Email_to_Contact__c != c.Send_Email_to_Contact__c)) && (c.Send_Email_to_Contact__c && !c.Do_not_Send_Email__c  && c.Email_of_Complainant__c!=null && c.Status!='Completed')) {
               system.debug('??????'+c.Send_Email_to_Contact__c);
           system.debug('Ram');
               sendEmailMessage(c.id,c.ownerId,c.Internal_Comments__c,c.Email_of_Complainant__c,c.Site_Details__c,c.CaseNumber,c.Case_Customer_Reference__c );
        }
           
              if ((trigger.isInsert || (trigger.oldMap.get(c.Id).Status != c.Status)) && (c.Final_email_to_contact__c && !c.Do_not_Send_Email__c  && c.Email_of_Complainant__c!=null && c.Status=='Completed')) {
           
                system.debug('****************'+c.Send_Email_to_Contact__c);
           
                sendFinalEmailMessage(c.id,c.ownerId,c.Internal_Comments__c,c.Email_of_Complainant__c,c.Site_Details__c,c.CaseNumber,c.Case_Customer_Reference__c);
        }
     
       }
}


Apex test class: code coverage just 52%

@isTest
public class TestClass_SendEmail{
static testmethod void SendEmails(){
Case cs = new Case(Status ='Outstanding',Complaint_Type__c ='Complaint',Query_Cause_Code__c='Disabled',Sub_Cause_Code__c ='Disabled',Send_Email_to_Contact__c=true,Final_email_to_contact__c=true,Email_of_Complainant__c='freak.abhinav@gmail.com');
insert cs;

cs.Status='Completed';
update cs;
}
Yoganand GadekarYoganand Gadekar
Hi,

Would like to add one Note: using static varibale to prevent recurssion does not work if you insert records with bulk API. You may need to use Set in case records will be inserted in bulk api