I have an issue with a trigger on opportunity. I have a method X in my opp_Handler that when opp.stageName changes to 'Closed Won' to execute code... the problem is, I have many methods my trigger is calling and it ends up that my method X runs multiple times and from those times it meets the conditions for 'Closed Won' twice. 'Closed Won' is updated through the interface by the user and not by code or workflow etc... I tried limiting my code with checkRecursive so my method only runs once but then it never meets the 'Closed one' criteria. So I did IF(Trigger.isAfter) system.debug('>>> Trigger.oldMap stage ' + Trigger.old[0].StageName); and it turns out that its prints 9 times, The first 4 it shows the old value as closed one, and only on the 5-6 time it shoes the real original value. So either I let my code run twice or it never meets the criteria. How do i fix this??? In the trigger context shouldent Trigger.OldMap Always carry the same values of the record before any changes were made? or do updates within the trigger somehow mess it up? Is it possible there are two instances of the trigger running some how because of an update one of the methods in the running trigger called?

1 Answer 1


It's called recursive trigger calls. And the main problem with it in Salesforce is that Trigger.oldMap always keeps the values record had before the very first time trigger was called. Here is what I use to pull the values record had just before the current trigger iteration, regardless how many times trigger was called before:

// map to hold myObject records values from previous iteration (that were processed in a trigger)
// used by AfterUpdate trigger
private static Map <Id,myObject__c> priorValuesMap = null;

// Initiating priorValuesMap, and populating original (before the trigger) myObject records values
if(priorValuesMap == null)
                                             // Collection Casting
    priorValuesMap = new map<Id,myObject__c>( (List<myObject__c>)Trigger.oldMap.values());

for(myObject__c record : Trigger.new)
    // Prior values for the idea
    myObject__c priorRecord = priorValuesMap.get(myObject__c.id);
    // your logic

// replace existing myObject records in the map with current values 
priorValuesMap.putAll( Trigger.new.deepClone(true, true, true));
  • Ok, so as I mentioned I have a method called "checkRecursive" which obviously would mitigate that issue of "recursive trigger calls". And as far as replacing the Trigger.oldMap with new values, thats not what I want to do. I do want the ORGINAL values, however as I mentioned I have a counter in my trigger and its running 9 times. so from 1-4 the old stageName shows the new value. 5-6 shows the old value. 7-9 is the new value. and each time I check I'm only looking at trigger.OldMap.
    – user8310
    Feb 22, 2017 at 7:10

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.