0

I am trying to update Opportunity Products when a value is changed on Product2.

SO when trigger is fired it is throwing the exception Apex cpu time limit exceeded

Here is my trigger:

trigger prod2trigger on Product2 (after insert,after update)
{
    for (Product2 prod2 : Trigger.new) {
        Product2 old;
        if(trigger.isupdate){
           old = Trigger.oldMap.get(prod2.Id);
        } 
        List<OpportunityLineItem> lineList = new List<OpportunityLineItem>();

        if(trigger.isinsert || (trigger.isupdate && (old.field__C != prod2.field__C ))) {
            List<OpportunityLineItem> oli = [Select id,OpportunityId,Product2Id from OpportunityLineitem where Product2Id =:prod2.id];
            for(OpportunityLineItem opli:oli){

                lineList.add(opli);
            }
            if(lineList.size()>0){
                update lineList; 
            }
        }
    }
}
  • 1
    I'm somewhat surprised that you ran into the CPU limit before running into the SOQL query limit. Queries inside of loops are bad, and you should work to remove your query from the loop over Trigger.new. Updating every OpportunityLineItem (OLI for short) for a given Product2 when that product changes also seems like a bad idea to me (doing so could lead to updating 10,000+ OLIs if this were in my org). – Derek F Aug 31 '17 at 20:28
  • 1
    As is, you haven't provided enough information to pin down the cause to your CPU limit issue. How many OLI records do you end up querying? Do you have any triggers on OLI, Opportunity, or Account? Any workflow rules with field updates? Any Process Builder Processes? Normally, tracking down the cause of a CPU limit issue takes a lot of digging through debug logs to reconstruct exactly what is being run (the analysis perspective of the dev console can help make that a little less painful). – Derek F Aug 31 '17 at 20:31
3

You've broken all the standard rules for database optimization, including querying inside a loop, DML inside a loop, unnecessary loop logic, and so on. At minimum, your code could be modified as follows:

trigger prod2trigger on Product2 (after update) {
  Set<Id> product2Id = new Set<Id>();
  for(Integer index = 0, size = trigger.new.size(); index < size; index++) {
    if(Trigger.old[index].field__c != Trigger.new[index].field__c) {
      product2Id.add(Trigger.new[index].Id);
    }
  }
  if(!product2id.isEmpty()) {
    update [SELECT Id FROM OpportunityLineItem WHERE Product2Id = :product2Id];
  }
}

I suspect that you'll have further complications along the road, depending on other triggers you have, etc, but this answer is directly aimed at reducing CPU usage in your trigger.

| improve this answer | |
  • Thanks for the response I am still getting the same error. I found that there is one more trigger running on Opportunity product, when an update is made on Product2 it is updating Opportunity products and related Opportunties – Learner Aug 31 '17 at 23:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.