Loading

Understanding Trigger.old and Trigger.new Salesforce Apex Triggers

Fecha de publicación: Mar 21, 2025
Descripción

This article describes how Trigger.old vs. Trigger.new values are used before or after any changes are made to Salesforce records.  Trigger.old and Trigger.new are Context Variables

To access the records that caused the trigger to fire, we use context variables. For example, Trigger.new contains all the records that were inserted in insert or update triggers. Trigger.old provides the old version of sObjects before they were updated in update triggers, or a list of deleted sObjects in delete triggers.

Triggers can fire when one record is inserted, or when many records are inserted in bulk via the API or Apex. Therefore, context variables, such as Trigger.new, can contain only one record or multiple records. You can iterate over Trigger.new to get each individual sObject.

 

Solución

Use Case

  • When a field value is updated to a certain value, we use trigger.old and trigger.new to compare the older and new version values of the field values on a record and perform the required business logic accordingly.
  • trigger.old is available only on the update and delete events and represents the old version of the records before the trigger event.
  • trigger.new is available only on insert, update, and undelete triggers and represents the new version of the records after the trigger event.

Example Scenario

    You have a workflow on an Account object creation that updates a field such as the "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.

    Rationale

    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 in the workflow because the example is an insert scenario.  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 below.

    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);
           
        }
    }

     

    Número del artículo de conocimiento

    000384697

     
    Cargando
    Salesforce Help | Article