0

I have written this trigger class and I'm getting the error 'maximum trigger depth exceeded'. I did my research and understood that the update function is being performed recursively. But I am new to this and I do not know how to rectify it. Could someone please help me?

The trigger class is given below. There are 2 fields in the account object called 'Start Date' and 'End date'. Whenever the custom field in the contact object 'Created Date' is between the Start and the End date, the checkbox 'Super Contact' must be checked. Where am I going wrong?

trigger SuperContact on Contact (after Insert, after update) {
      set<Id> setAccId = new Set<Id>();
      Static Boolean b ;
          List<Contact> conListUpdate = new List<Contact>();
            for(contact con: Trigger.new){
                  //  if(con.AccountId!=null){
                        setAccId.add(con.AccountId);               
                  //  }
            } 

                  if(Trigger.isAfter && Trigger.isUpdate){

                    //  map<Id,Account> mapAccount = new map<id,Account>([SELECT id,name FROM Account WHERE Id IN:setAccId]);

                       for(contact con: Trigger.New){
                         b = true;
                       Account a = new Account();
                       a = [SELECT id,Start_date__c, End_Date__c FROM Account WHERE ID=: con.AccountId];
                          if(a.Start_Date__c<=con.Created_Date__c && con.Created_Date__c<=a .End_Date__c){
                              Contact c = new Contact();

                              c.Super_Contact__c=true;
                              c.id = con.Id;
                              conListUpdate.add(c) ; 

                          }
                       }

                        if(Trigger.isAfter && Trigger.isInsert){

                    //  map<Id,Account> mapAccount = new map<id,Account>([SELECT id,name FROM Account WHERE Id IN:setAccId]);

                       for(contact con: Trigger.New){
                         b = true;
                       Account a = new Account();
                       a = [SELECT id,Start_date__c, End_Date__c FROM Account WHERE ID=: con.AccountId];
                          if(a.Start_Date__c<=con.Created_Date__c && con.Created_Date__c<=a .End_Date__c){
                              Contact c = new Contact();

                              c.Super_Contact__c=true;
                              c.id = con.Id;
                              conListUpdate.add(c) ; 

                          }
                       }}

                       if(b==true){
                       update conListUpdate;
                       b=false;} 

         }  

    }
1

2 Answers 2

1

Why not just use a formula field instead or a WFR Field Update

if(Account.Start_Date__c <= Created_Date__c && Created_Date__c <= End_Date__c, true, false)

Working on example for code to help you lear what to do. give me a sec

trigger

trigger setSuperContact on Contact(After Insert, After Update){

    if(superContact.alreadyRan) return;

    superContact.checkValues(trigger.new);



}

Class

public class superContact{


    public static boolean alreadyRan = false;

    public static void checkValues(Contact[] con){
        //prevent recursion
        alreadyRan = true;
        Map<ID,Contact[]> accToCon = New Map<ID,Contact[]>();
        Contact[] conTBU = New Contact[]{};

        //Map AccountID to Contacts
        for(Contact c : cons){
            if(c.AccountID != null){
                //Doing this way as performance is better
                Contact[] tmp = accToCon.get(c.AccountID);
                if(tmp == null) tmp = New Contact[]{};
                tmp.add(c);
                accToCon.put(c.AccountID,tmp);

            } 
        }

        Map<ID,Account> accts = New Map<ID,Account>([Select SELECT id,Start_date__c, End_Date__c FROM Account WHERE ID IN :accToCon.keySet()]);

        //Go through accounts and then the related contacts
        //you could also do it using a subquery for contacts which may be more appropriate
        //How to you handle setting contacts previously marked as true that have passed the critera values but do not get updated? Do you do a daily batch update?
        for(Account a : accts){
            Contact[] tmp = accToCon.get(a.id);

            for(Contact c : tmp){
                Boolean isSuper = a.Start_Date__c <= c.Created_Date__c && c.Created_Date__c <= a.End_Date__c
                c.Super_Contact__c = isSuper;
                conTBU.add(c);
            }
        }

        update conTBU;

    }


}

May not be completely optimized as it is really late and been one of those days

You should strive to move all code from a trigger to a separate class and leave minimal code int he trigger

See questions in code. A formula field may be a better option if you can do it.

2
  • The requirement was to do it using triggers. The code that you have posted worked but I have modified my code differently and that works too. Anyway, thank you so much :)
    – User2529
    Nov 5, 2015 at 9:39
  • Just because a requirement was to write a trigger does not mean you HAVE to do it via a trigger if a configurable route would do the same thing. All you have to do is ASK and EXPLAIN. Anyway, please mark as accepted answer so it does not keep surfacing
    – Eric
    Nov 5, 2015 at 15:32
0

I wrote a class for my trigger and called it as the before function in my trigger. Anyway thanks all!

public with sharing class superContactHandler{
        public void contactMethod(list<Contact> newContact){
            Set<Id> setAccId = new Set<Id>();
            Boolean b = true;    
            for(contact con: newContact){
                setAccId.add(con.AccountId);               
            }
            Map<id,Account> accMap = new Map<id,Account>([SELECT id,Start_date__c, End_Date__c FROM Account WHERE ID IN : setAccId]);
            for(contact con: newContact){
                Account a = accMap.get(con.AccountId);
                if(a.Start_Date__c<=con.Created_Date__c && con.Created_Date__c<=a.End_Date__c){
                    con.Super_Contact__c=true;
                }
                else{
                    con.Super_Contact__c=false;
                } 
            }
        } 

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .