+ Start a Discussion
Michael Anderson 40Michael Anderson 40 

Extra recursion on my trigger!

I have an after update trigger that is firing 3 times when I run my test class. It only fires twice when I update the record through the UI. I'm stumped!

When I run my test class, the very first time the trigger fires, trigger.New and trigger.Old values appear to be the same, which is not what I expect to see in the debug log. The second time it fires I can see that the new and old values are different, which is what I expect. I know that one of the additional trigger runs is due to a workflow field update on the Account, that's fine. 

I can control the recursion through a static variable in my class, as I would normally do, but the problem here is that the recursion control stops the trigger after the first run, and in the first run the old and new values are the same so my trigger logic doesn't work as I would expect.

I've stripped out most logic from the code so that now it's just a plain vanilla textbook setup. 
 

trigger AccountTrigger on Account (after update) {
     AccountHelper.runUpdate();
}

public class AccountHelper {

     public static void runUpdate(){

              system.debug(trigger.New[0].custom_field__c);
              system.debug(trigger.Old[0].custom_field__c);

     }
}

@isTest
public class AccountHelperTest{

     private static testmethod void testThis{

           Account a = new Account(Name='TestAccount');
           insert a;

           a.custom_field__c = 'Changed';
           update a;
      }
}
When I run the test, with a workflow field update on the Account, I see this in the debug log:
1 newvalue = null
2 oldvalue = null
3 newvalue = Changed
4 oldvalue = null
5 newvalue = Changed
6 oldvalue = null

When I open an account through the UI and change the custom field and save, the debug will show only lines 3 through 6.

Any ideas would be greatly appreciated!
Alain CabonAlain Cabon
@Michael Anderson

1 newvalue = null
2 oldvalue = null

It is impossible with just "after update" , that means also "after insert" for example in an other trigger.

By the way, your posted code is incomplete and cannot work as it is for AccountHelper (stripped out most logic from the code).
Michael Anderson 40Michael Anderson 40
An update: I've determined that the update operation is not causing the trigger to fire 3 times, it just appeared that way.

What is happening: during the insert operation there is a workflow field update that updates the Account, then the code goes back and re-fires the triggers, as expected. However, it is firing the after update trigger, even though this is an insert operation.

From the developer users guide (https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_order_of_execution.htm):
The refiring of triggers isn't limited to updates, but applies to all operation types. A workflow field update that fires on record insert will rerun any before and after insert triggers again—as insert triggers.

So why is the after update trigger firing in an insert operation? Is the documentation incorrect, or am I reading it wrong?
Alain CabonAlain Cabon
@Michael

It is a workflow rule with a field update.

System.TriggerOperation triggerOperation

 system.debug(triggerOperation + '>' + trigger.New[0].custom_field__c);
 system.debug(triggerOperation + ' >' + trigger.Old[0].custom_field__c);

It is always an AFTER_UPDATE ( trigger AccountTrigger on Account (after update) { )

But these first values (1, 2) are not expected indeed and that seems an update after the insert when the values are all null (workflow) but the workflow is always executed after the trigger otherwise (?).

1 newvalue = null
2 oldvalue = null

The expected logic would be:
https://www.jitendrazaa.com/blog/salesforce/why-to-avoid-using-workflow-rule-and-process-builder-field-update-with-trigger/