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
sfdc dev 2264sfdc dev 2264 

System.LimitException: Apex CPU time limit exceeded help needed

Hi ,

I have a trigger where i am getting the following exception often 

System.LimitException: Apex CPU time limit exceeded

Please help me how to fix this issue
MY TRIGGER :

trigger AccconRshipUpdate on Contact (after insert, after Update,after delete,after undelete){

    try{
        Trigger_Status__c ts = Trigger_Status__c.getValues('AccconRshipUpdate');
        if(ts.Active__c) { 
    if ((trigger.isafter && trigger.isInsert) || (trigger.isafter && trigger.isUpdate)) {
            accConRshipUpdateonContacts.AccContactInsUpdate(trigger.new);
          }
    if ((trigger.isafter && trigger.isInsert) || (trigger.isafter && trigger.isUpdate) || (trigger.isafter && trigger.isdelete)|| (trigger.isafter && trigger.isUndelete))      
         {
          Contact[] cons;
            if (Trigger.isDelete)
                    cons = Trigger.old;
            else
                    cons = Trigger.new;
            RollupofCLcontactsHandler.CountNumofContacts(cons);    
         } 
       }
   }catch(Exception e){
        System.debug('Error Occured From AccconRshipUpdate  Trigger: '+e.getMessage());
    }
}



Kindly help me pls

Thanks in Advance
JLA.ovhJLA.ovh
You should have a look either at accConRshipUpdateonContacts.AccContactInsUpdate() or RollupofCLcontactsHandler.CountNumofContacts(). Focus on loops and cpu intensive methods
sfdc dev 2264sfdc dev 2264
Ok , Her is my both the classes

Pls help me what is wrong in it
 
MY APEX CLASS 1 :

Public class accConRshipUpdateonContacts {

    public static void AccContactInsUpdate(list<Contact> listOfCon) {
    
    set<Id> ConIds = new set<Id>();
    map<Id, Contact> mapContact = new map<Id, Contact>();
    list<AccountContactRelation> listOfAccConRel = new list<AccountContactRelation>();
    //Freight change Start
    set<Id> AirportcodeIds = new set<Id>();
    list<Airport_Code__c> listOfAirportcode = new list<Airport_Code__c>();
    map<Id, Airport_Code__c> mapAirportcode = new map<Id, Airport_Code__c>();
    //Freight change End
    
    for(Contact Cont : listOfCon) {
        ConIds.add(Cont.Id);
        mapContact.put(Cont.Id, Cont);
        //Freight change
        AirportcodeIds.add(Cont.Freight_Contact_City__c);
    }
    
     //Freight change Start
    listOfAirportcode =[Select Id,Name from Airport_Code__c where id In :AirportcodeIds ];
    
    if(listOfAirportcode.size() > 0)
    {
        for(Airport_Code__c aico : listOfAirportcode) {
            mapAirportcode.put(aico.id, aico);
        }
    }
     //Freight change End
    
    listOfAccConRel = [SELECT Function__c,Business_Type__c,Job_Role__c,ContactId,IsDirect, Freight_City__c FROM AccountContactRelation WHERE ContactId IN : ConIds];
    system.debug('***SOQLUPDATEACR***'+ listOfAccConRel ); // City__c
    
    if(listOfAccConRel.size() > 0 && listOfAccConRel.size() <= 1){
       system.debug('***SizeofACR***'+ listOfAccConRel.size());
       
        for(AccountContactRelation accCon : listOfAccConRel) {
            accCon.Function__c = mapContact.get(accCon.ContactId).Function__c;
            accCon.Business_Type__c = mapContact.get(accCon.ContactId).Business_Types__c;  
            accCon.Job_Role__c = mapContact.get(accCon.ContactId).Job_Role__c;
            system.debug('***ACR***'+ accCon.Job_Role__c);
            acccon.Job_Title__c = mapContact.get(accCon.ContactId).Job_Title__c;
            acccon.Related_Phone__c = mapContact.get(accCon.ContactId).Phone;
            //Freight change Start
            if(mapAirportcode.size() > 0)
             {
              acccon.Freight_City__c = mapAirportcode.get(mapContact.get(accCon.ContactId).Freight_Contact_City__c).Name;
             }
             //Freight change End
            acccon.Related_Email__c = mapContact.get(accCon.ContactId).Email;                    
         }
            Database.update(listOfAccConRel);
            system.debug('***UPDATEACR***'+ listOfAccConRel); 
      } 
   }
}
 
MY APEX CLASS 2 :

public class RollupofCLcontactsHandler {
        public static void CountNumofContacts(List < Contact > newList) {
            Set<ID> acctIds = new Set<ID>();
  try {
       // get list of accounts

    for (Contact con : newList) {
            acctIds.add(con.AccountId);
    }
   
    Map<ID, Contact> contactsForAccounts = new Map<ID, Contact>([select Id
                                                            ,AccountId
                                                            from Contact
                                                            where AccountId in :acctIds and Profile_CL_Flag__c=TRUE]);

    Map<ID, Account> acctsToUpdate = new Map<ID, Account>([select Id
                                                                 ,Chairmans_Lounge__c
                                                                  from Account
                                                                  where Id in :acctIds]);
                                                                
    for (Account acct : acctsToUpdate.values()) {
        Set<ID> conIds = new Set<ID>();
        for (Contact con : contactsForAccounts.values()) {
            if (con.AccountId == acct.Id)
                conIds.add(con.Id);
        }
        if (acct.Chairmans_Lounge__c != conIds.size())
            acct.Chairmans_Lounge__c = conIds.size();
    }

    update acctsToUpdate.values();

  }
  
  catch(Exception e){
        System.debug('Error Occured From RollupofCLcontacts  Handler: '+e.getMessage());
    }
}
}

These are the 2 apex classes referred n that above trigger

Kindly help me to fix this issue 

Thanks
JLA.ovhJLA.ovh
Not related to your issue, but you could change
if(listOfAccConRel.size() > 0 && listOfAccConRel.size() <= 1){

into
if(listOfAccConRel.size() == 1){
You should put invariants outside of the loops. For instance 
if(mapAirportcode.size() > 0)

is invariant, giving always the same result during the whole for() loop. You could have Boolean nonEmptyAirportCode=(mapAirportcode.size() > 0)  then replacing your test into "if(nonEmptyAirportCode)". It consumes less cpu to do less evaluations.
Same for "mapContact.get(accCon.ContactId)" : you evaluate this 7 times while you could evaluate it only once

You can make your code simpler too. With less instructions, it is sometimes quicker. For instance, instead of
list<Airport_Code__c> listOfAirportcode = new list<Airport_Code__c>();
    listOfAirportcode =[Select Id,Name from Airport_Code__c where id In :AirportcodeIds ];
    if(listOfAirportcode.size() > 0)
    {
        for(Airport_Code__c aico : listOfAirportcode) {
            mapAirportcode.put(aico.id, aico);
        }
    }

You could write
for(Airport_Code__c aico : [Select Id,Name from Airport_Code__c where id In :AirportcodeIds ]) {
            mapAirportcode.put(aico.id, aico);
}
Not much reducing cpu, mostly reducing heap and apex code size (which is another governor limit)

 This code is too much complex
if (acct.Chairmans_Lounge__c != conIds.size())
            acct.Chairmans_Lounge__c = conIds.size();
while this one
acct.Chairmans_Lounge__c = conIds.size();
gives the same result. In fact, the best would be to keep the test and construct another list to update only accounts that have changed. This will reduce the quantity of cascade triggers and cascade code executed, improving performance and CPU