+ Start a Discussion
Bryan CerratiBryan Cerrati 

Apex CPU Time Limit

i have a class and trigger that takes a string from a custom field on an account that it is associated with a custom object "Wholesale Pipeline" and places the account name into the account lookup field in the custom object. 
 
public with sharing class addNMLSPipeline 
{
	public void addNMLS(List<Wholesale_Pipeline__c> lstPipeline)
	{
		addNMLSPrivate(lstPipeline);
	}
	private void addNMLSPrivate(List<Wholesale_Pipeline__c> lstPipeline)
	{
		Set<String> accId = new Set<String>();
		for(Wholesale_Pipeline__c accloop : lstPipeline)
			accId.add(accloop.NMLS__c);
		List<Account> lstAcc = new List<Account>([SELECT Id, Name, NMLS_Number__c FROM Account WHERE NMLS_Number__c =: accId LIMIT 1]);
		for(Account accloop2 : lstAcc)
		{
			for(Wholesale_Pipeline__c pipe : lstPipeline)
				if(pipe.NMLS__c != null)
					pipe.Account__c = accloop2.Id;
		}
	}
}

when i update the pipeline object records with a nmls using the data loader i get about 200 records succeed and 800 fail saying "Apex CPU time limit exceeded"

can someone please help me, i have looked at a million links and even other posts that deal with similar problems but dont seem to understand where i have gone wrong. 
 
Best Answer chosen by Bryan Cerrati
Amit Chaudhary 8Amit Chaudhary 8
Try below code
private void addNMLSPrivate(List<Wholesale_Pipeline__c> lstPipeline)
{
	Set<String> pipeNMLS = new Set<String>();
	for(Wholesale_Pipeline__c accloop : lstPipeline)
	{
		pipeNMLS.add(accloop.NMLS__c);
	}
	
	List<Account> lstAcct = new List<Account>([SELECT Id FROM Account WHERE NMLS_Number__c =: pipeNMLS ]);
	
	Map<String,Account> mapNMLSWiseAcc = new Map<String,Account>();
	for(Account acc : lstAcct)
	{
		mapNMLSWiseAcc.put(acc.NMLS_Number__c , acc);
	}	
	
	for(Wholesale_Pipeline__c pipe : lstPipeline)
	{
		if(pipe.NMLS__c != null && pipe.NMLS__c.isNumberic() && mapNMLSWiseAcc.containsKey(pipe.NMLS__c) )
			pipe.Account__c = mapNMLSWiseAcc.get(pipe.NMLS__c).id;
		else
			pipe.Account__c = null;
	}
}

Let us know if this will help you
 

All Answers

Charan Thumma 15Charan Thumma 15
Hi Bryan,

Take out the SOQL from the for loop and then use your list(accId) in SOQL. It should resolve your issue. 
Bryan CerratiBryan Cerrati
theres no SOQL in the for loop. 
Charan Thumma 15Charan Thumma 15
Bryan,


I apologize... Is there a reason why you limit the results to just 1 record?  Can you please try with out limit in SOQL... 
Amit Singh 1Amit Singh 1
Bryan,

You have used for indide for loop. Try to use only a single for loop. You can minimise using collection like list, set and MAP.

Also, how do you define the relationship between Account and Wholesale_Pipeline__c Object.

Let me know the outcomes.

Thanks,
Amit Singh.
LBKLBK
List<Account> lstAcc = new List<Account>([SELECT Id, Name, NMLS_Number__c FROM Account WHERE NMLS_Number__c =: accId LIMIT 1]);
		for(Account accloop2 : lstAcc)
		{
			for(Wholesale_Pipeline__c pipe : lstPipeline)
				if(pipe.NMLS__c != null)
					pipe.Account__c = accloop2.Id;
		}
In this above piece of code, you have added a for loop on lstAcc which has only one record.

Can you get rid of this for loop?
 
Bryan CerratiBryan Cerrati
i tried taking out the account loop and making it just a object.
 
private void addNMLSPrivate(List<Wholesale_Pipeline__c> lstPipeline)
	{
		Set<String> accId = new Set<String>();
		for(Wholesale_Pipeline__c accloop : lstPipeline)
			accId.add(accloop.NMLS__c);
		Account lstAcc;
		lstAcc = [SELECT Id FROM Account WHERE NMLS_Number__c =: accId LIMIT 1];
		for(Wholesale_Pipeline__c pipe : lstPipeline)
			if(pipe.NMLS__c != null)
				pipe.Account__c = lstAcc.Id;
	}

the code works but i still get some errors like :

addNMLSPipelineTrigger: execution of BeforeUpdate
caused by: System.QueryException: List has no rows for assignment to SObject()

is this because if the record entering the trigger doesnt have a nmls__c or the account doesnt have a NMLS_Number__c  filled out?

 
Amit Chaudhary 8Amit Chaudhary 8
Hi Bryan Cerrati ,

Issue is coming because of for loop inside the for loop. Try to update your code like below
public with sharing class addNMLSPipeline 
{
	public void addNMLS(List<Wholesale_Pipeline__c> lstPipeline)
	{
		addNMLSPrivate(lstPipeline);
	}
	private void addNMLSPrivate(List<Wholesale_Pipeline__c> lstPipeline)
	{
		Set<String> accId = new Set<String>();
		for(Wholesale_Pipeline__c accloop : lstPipeline)
		{
			accId.add(accloop.NMLS__c);
		}
		
		List<Account> lstAcc = new List<Account>([SELECT Id, Name, NMLS_Number__c FROM Account WHERE NMLS_Number__c =: accId ]);
		Map<String,Account> mapNMLSWiseAcc = new Map<String,Account>();
		for(Account acc : lstAcc)
		{
			mapNMLSWiseAcc.put(acc.NMLS_Number__c , acc);
		}
		
		for(Wholesale_Pipeline__c pipe : lstPipeline)
		{
			if( pipe.NMLS__c != null && mapNMLSWiseAcc.containsKey(pipe.NMLS__c) )
			{
				pipe.Account__c = mapNMLSWiseAcc.get(pipe.NMLS__c).Id;
			}	
		}
	}
}

Let us know if this will help you

 
Bryan CerratiBryan Cerrati
Hi the Amit Chaudhary, 

thats absolutly BEAUTIFUL! i understand how the map is used in this case now. 

i wrote something similar without mapping do you think this works as well?
 
private void addNMLSPrivate(List<Wholesale_Pipeline__c> lstPipeline)
	{
		Set<String> pipeNMLS = new Set<String>();
		for(Wholesale_Pipeline__c accloop : lstPipeline)
			pipeNMLS.add(accloop.NMLS__c);
		List<Account> lstAcct = new List<Account>([SELECT Id FROM Account WHERE NMLS_Number__c =: pipeNMLS LIMIT 1]);
		Id accId;
		if(!lstAcct.isEmpty())
		{
			for(Account accLoop : lstAcct)
				accId = accLoop.Id;
		}		
		for(Wholesale_Pipeline__c pipe : lstPipeline)
		{
			if(pipe.NMLS__c != null && pipe.NMLS__c.isNumberic())
				pipe.Account__c = accId;
			else
				pipe.Account__c = null;
		}
	}

 
Amit Chaudhary 8Amit Chaudhary 8
Try below code
private void addNMLSPrivate(List<Wholesale_Pipeline__c> lstPipeline)
{
	Set<String> pipeNMLS = new Set<String>();
	for(Wholesale_Pipeline__c accloop : lstPipeline)
	{
		pipeNMLS.add(accloop.NMLS__c);
	}
	
	List<Account> lstAcct = new List<Account>([SELECT Id FROM Account WHERE NMLS_Number__c =: pipeNMLS ]);
	
	Map<String,Account> mapNMLSWiseAcc = new Map<String,Account>();
	for(Account acc : lstAcct)
	{
		mapNMLSWiseAcc.put(acc.NMLS_Number__c , acc);
	}	
	
	for(Wholesale_Pipeline__c pipe : lstPipeline)
	{
		if(pipe.NMLS__c != null && pipe.NMLS__c.isNumberic() && mapNMLSWiseAcc.containsKey(pipe.NMLS__c) )
			pipe.Account__c = mapNMLSWiseAcc.get(pipe.NMLS__c).id;
		else
			pipe.Account__c = null;
	}
}

Let us know if this will help you
 
This was selected as the best answer
Steve LovelySteve Lovely
Im in the same boat and at my wits end

trigger RG_WorkOrderTgr on WorkOrder (before insert,before update, after insert) {
    if (Trigger.isInsert && Trigger.isAfter) {
        RG_WorkOrderCloseHandler.recursionFlag = false;
        RG_WorkOrderCloseHandler.ticketcloseDateUpdate(Trigger.new, Trigger.newMap, Trigger.isInsert, false);
        WorkOrderSendEmailHandler.sendEmailAfterInsert(Trigger.new);
        System.debug('Trigger.isInsert after'+Trigger.isInsert);

    } else if ( Trigger.isUpdate && RG_WorkOrderCloseHandler.recursionFlag && !RG_WorkOrderCloseHandler.isUpdateRecursive) {
        RG_WorkOrderCloseHandler.isUpdateRecursive = true;
        RG_WorkOrderCloseHandler.recursionFlag = false;
        RG_WorkOrderCloseHandler.ticketcloseDateUpdate(Trigger.new, Trigger.newMap, false, True);
        System.debug('Trigger.isUpdate after'+Trigger.isUpdate);
    }

    if (Trigger.isBefore) {
        if (Trigger.isInsert && Trigger.isBefore) {
            Map<Id,WorkOrder> casemap = new Map<Id,WorkOrder>();
            RG_WorkOrderPriorityFiedlMappingCls.priorityFiedlMappingBeforeInsert(Trigger.new,casemap, true);
            System.debug('Trigger.isInsert before '+Trigger.isInsert);
        }

        if (Trigger.isUpdate) {
            Map<Id,WorkOrder> casemap = new Map<Id,WorkOrder>();
            if(Trigger.oldMap!=NULL)
                casemap = Trigger.oldMap;
            
            RG_WorkOrderPriorityFiedlMappingCls.priorityFiedlMappingBeforeInsert(Trigger.new,casemap, False); 
            //RG_WorkOrderCloseHandler.ticketcloseDateUpdate(Trigger.new, Trigger.newMap, false, true);
            if(WorkOrderSendEmailHandler.isUpdateRecursive!=NULL && !WorkOrderSendEmailHandler.isUpdateRecursive){
                WorkOrderSendEmailHandler.isUpdateRecursive = true;
                WorkOrderSendEmailHandler.sendEmailAfterStatusUpdate(Trigger.newMap, Trigger.oldMap);
            }
           
            System.debug('Trigger.isUpdate before '+Trigger.isUpdate);
        }
    }
}