Print this page

Understand Trigger.old and Trigger.new values in before & after update triggers

Knowledge Article Number 000003789
Description

Find out more about how Trigger.old vs. Trigger.new values in before & after update triggers. Trigger.old won't hold the newly updated field by the workflow after the update.

Resolution

Considerations

  • You have a workflow on an object creation - say Account - that updates a field - for example "description" field.
  • You then have a trigger that fires after the workflow update and iterates over trigger.old expecting to get the "description" field that was modified by the workflow.
  • In this case you will get a nullpointerException.

Rational

The reason comes down to understanding the values held by these 2 data structures.

Trigger.old values will be the same before and after the CURRENT transaction (user action). The same applies to Trigger.new.

In other words - Trigger.old won't hold the newly updated field by the workflow after the update. However, if we proceed to manually edit the record, the trigger will fire again (and this is viewed as a new “update transaction”). Trigger.old will hold the field that was updated on the previous transaction by the workflow rule.

Going back to the example above: 

The values in Trigger.old after the workflow update will NOT contain the “description” field that was updated in the workflow.

The values in Trigger.new after the workflow update will contain any existing fields that were populated upon the object’s creation AND the “description” workflow updated field.

You'll have to query the database after the workflow field update fires In order to obtain that same field.

For example:
 

List<Account> accts = [Select Id, FieldUpdatedByWorkflow__c from Account where Id in : Trigger.old];

See the sample trigger bellow.

Note: Create a workflow field update on Account objects creation to see the results in the debug log.

trigger testTrigger on Account (before update, after update, before insert, after insert) 
 
{
    if (Trigger.isBefore) {
        System.debug('********Trigger values***********');
        System.debug('***SFDC: Trigger.old is: ' + Trigger.old);
        System.debug('***SFDC: Trigger.new is: ' + Trigger.new);
    }
    
    if (Trigger.isAfter) {
        System.debug('********Trigger values***********');    
        System.debug('***SFDC: Trigger.old is: ' + Trigger.old);
        System.debug('***SFDC: Trigger.new is: ' + Trigger.new);
       
    }
}