Salesforce Trigger Interview Question

Triggers are an important part of Salesforce Apex customization. Apex triggers enable you to perform custom actions before or after events to records in Salesforce, such as insertions, updates, or deletions.


6 min read
  1. What is Trigger and when should you prefer a trigger over other available tools?

A trigger is an apex code which is invoked when a Database operation occours within saleforce - This can be made to un before or after the operation.

The Database Operation or DML (Data Manupulation Language) operations supported in Salesforce are - insert, update, delete and undelete

As for the question- Should it be preferred over other tools ? - This depends on certain factors: As a rule in salesforce - we must choose configuration (point and click changes) over customization (code changes) so a textbook answer would prefer a process builder or Workflow over a trigger.

However, the scenario changes when working with huge volumes and data - especially if we want certain operations to be performed across those records. In such cases - configurative entities such as a Workflow or Process Builder would run for each of the records in a transition (So a load of 100 records would cause the Workflow to fire 100 times) - This may cause performance issues especially with respect to CPU time. In such cases - a Bulkified trigger would process records in batches of 200 and may be more efficient - There are also other factors to consider such as the column of WF's and PBs in place.

To summarize - there is not perfect answer to this question as it is dependent on the situation and the governor limits applicable in the implementation org.

  1. What are the different context variables in Trigger?

Context variables are those variables which are available in the context in which a trigger executes. They are populated and provided to the developer in the context of the DML operation. We can access these variables using the Trigger(dot) notation. They are

  • Trigger.isExecuting --> True if code is running because of a trigger
  • Trigger.isInsert --> True if insert operation is performed
  • Trigger.isUpdate --> True if update operation is performed
  • Trigger.isDelete --> True if delete operation is performed
  • Trigger.isBefore --> True if code is running before the record is committed
  • Trigger.isAfter --> True if code is running after the record is committed
  • Trigger.isUndelete --> True if undelete operation is performed
  • Trigger.new --> A List variable storing a list of new values of the records
  • Trigger.newMap --> A Map if record ID(key) and the new values of the records
  • Trigger.old --> A List variable storing a list of old values of the records
  • Trigger.oldMap --> A Map if record ID(key) and the old values of the records
  • Trigger.operationType --> Returns the context & operation Eg ()
  • Trigger.size --> Returns the number of records which invoked the trigger
  1. What is the difference between Trigger.New & Trigger.NewMap?

The Datatype Trigger.New is a list of SObjects and it holds the "new" record values of the record . It will hold all the values of the record irrespective of whether it was changes or not.

The Datatype of Trigger.NewMap is a Map of recordID and Sobject and the Sobject would hold the "new" values of the record.

Example :
When a trigger executes because of a Update DML Operation on Account where the account name was changed from 'TeachMeTriggers' to 'KTGuru' for a single account.

Trigger.New would be a List having 1 record having all the fields of account populated and the name field will have the value 'KTGuru' (the new value).

Trigger.NewMap would be a Map<id,Account> where the key will be the Salesforce id of the Account.

Because when we delete a record - The "new" version of the record does not exist. Trigger.New will be NULL when the DML operation is Delete

  1. What is the difference between Trigger.Old & Trigger.OldMap?

The Datatype Trigger.Old is a list of SObjects and it holds the "old" record values of the record . It will hold all the old values of the record irrespective of whether it was changes or not.

The Datatype of Trigger.OldMap is a Map of recordID and Sobject and the Sobject would hold the "old" values of the record.

Example :
When a trigger executes because of a Update DML Operation on Account where the account name was changed from 'TeachMeTriggers' to 'KTGuru' for a single account.

Trigger.New would be a List having 1 record having all the fields of account populated and the name field will have the value 'TeachMeTriggers' (the old value).

Trigger.OldMap would be a Map<id,Account> where the key will be the Salesforce id of the Account.

Because when we create a record - The "old" version of the record does not exist. Trigger.Old will be NULL when the DML operation is Insert

  1. Can we do DML in Trigger.Before ? If No, Why Not.

Well this is definitely not recommended but is it posible? - Well that depends - On whether you are trying to udpate a record of the same object (directly or indirectly) or you are trying to update a completely disconnected record.

As for why should we not /Can't do this ? - Well the before insert portion of the code run before the record is actually commited to the database so the ideal purpose of the code is to perform validations/Changes to the current set of records before it is commited to the Database. Also if you are directly or indirectly updating the same object - This could cause a recursive execution of the trigger.

Example : DML on Object A --> Before Triggers of Object A --> DML on Object A --> Before Trigger of Object A....and so on..

  1. Can we make changes to the Trigger.New or Trigger.old Data?

    Trigger.New, Yes - Especially within before triggers if you make changes to Trigger.New - The updated values will be committed to the Database.

    Trigger.Old is the original values of the record - It would not make sense to make changes to these values.

  2. What is a recursive trigger and How to avoid it?

    Triggers which directly or indirectly invoke themselves are called recursive triggers.

    Example 1 : If an update on Account "Acc1" causes a trigger on Account to Update a contact record "Con1" and the trigger on Contact in-turn updates the Account "Acc1" - This might cause an infinite recursion and the transaction would fail.

    Example 2 : update of Account "Acc1" causes the trigger and then the WF to run , the workflow performs a field update and in-turn caused the triggers to run again for "Acc2" (In this case the WF would not run a second time - by design but it is still inefficient)

To avoid this create s static variable within a class and check the value of this field before executing the logic of the trigger. The reason the variable needs to be static is because the value will not the reinitialised the second time the trigger is invoked (through the list of the execution).

  1. What is the best practice for writing a trigger?

    All the best practices of writing Apex code would automatically apply to writing and Apex triggers such as " don’t Perform SOQL/DML inside a loop" as we may run into the governor limits. In addition to these, specifically for triggers -

    a) try to create only a single trigger per object as this could cause an unpredictability in the order of execution as there is no way to guess which trigger would execute first.

    b) It is also recommended to create a helper class and write the bulk of the code there - This would streamline the code and also make it more readable.

    c) Always bulkify your triggers - if you perform an DML operation on object for say 1000 records, he trigger would internally run for every batch of 200 records - So the trigger would run 5 times (1000 / 200) and not a 1000 times and trigger.New would hold the list of those 200 records during each execution and you must write the triggers in such a way that you don't run into governor limits when the code executes in bulk.

    d) As mentioned earlier, try not to perform DML operations in before triggers.

  2. **Can we make a callout from the trigger? If Yes, then how? **

    Yes, using a future call - The reason for this is that when we save a record into the database, we cannot wait for a callout and acknowledgement as they may be time consuming. So the workaround is to make the transaction asynchronous by invoking a future method and making the callout within the future methods.

  3. **Can we execute a batch class from the trigger? **

This is also not recommended but yes, it is possible. You can call a batch class using database.Executebatch - However, if the batch class is performing a DML operation on the same object - The process would fail because a batch/Future method cannot invoke another batch/future method directly.

If you must use System.isBatch() or System.isFuture() checks to ensure that this does not happen.

Related Articles

GO TOP

🎉 You've successfully subscribed to KTguru!
OK