Introduction
Triggers are a fundamental aspect of Salesforce development, and most technical interviews include questions about triggers.
Before wasting any time, lets start with all possible interview questions on Salesforce triggers.
1. What are Salesforce Triggers?
Triggers are pieces of Apex code that execute automatically when specific DML events (like insert, update, upsert or delete) occur on Salesforce objects.
They allow custom business logic to run during these events.
2. What are the types of triggers in Salesforce?
There are 2 types of triggers in Salesforce:
Before Trigger: Executes before a record is saved to the database. Commonly used for data validation or modification in the same object that caused the trigger to fire.
After Trigger: Executes after a record is saved to the database. Commonly used for creating or updating related records or sending notifications.
3. List some common use cases for triggers.
- Automatically populating fields on child objects when the parent is updated.
- Preventing duplicate records during data insertion.
- Creating audit logs for updates or deletions.
- Automatically triggering callout when the record in a particular object is inserted or updated.
4. What are Trigger Context Variables?
Trigger context variables provide information about the current DML operation. For example:
- Trigger.new:
Contains new values of records during insert or update operation. - Trigger.old:
Contains original values of records during update or delete operation. - Trigger.newMap:
A map of IDs to the new values of records during insert or update. - Trigger.oldMap:
A map of IDs to the original values of records during update or delete. - Trigger.isInsert:
Returns true if the current operation is an insert. - Trigger.isUpdate:
Returns true if the current operation is an update. - Trigger.isDelete:
Returns true if the current operation is a delete. - Trigger.isBefore:
Returns true if the trigger is executed before the DML operation. - Trigger.isAfter:
Returns true if the trigger is executed after the DML operation. - Trigger.isExecuting:
Returns true if the trigger is currently executing. - Trigger.size:
Returns the total number of records being processed in the current trigger.
- Trigger.new:
5. What is the difference between Trigger.new and Trigger.old?
Trigger.new: Holds the new values of records being inserted or updated.
Trigger.old: Holds the original values of records before an update or deletion.
6. How many records can a trigger process at a time?
Triggers in Salesforce are designed to handle up to 200 records at a time in a single transaction, which means the batch size for a trigger is 200.
For example: If there are 1000 records to be processed by a trigger, the trigger will execute 5 times, with each batch processing 200 records.
This ensures that triggers efficiently handle large volumes of data while adhering to Salesforce’s governor limits.
7. What is the syntax of a basic trigger?
Here’s an example of a simple trigger on Account Object:
The syntax of a trigger is:
trigger TriggerName on ObjectName (before insert) {
}
}
Sample Trigger on Account object
trigger AccountTrigger on Account (before insert) {
for (Account acc : Trigger.new) {
acc.Name = 'Default Account Name';
}
}
8. When do you use a Before Trigger vs. an After Trigger?
Before Trigger: Executes before a record is saved to the database. Commonly used for data validation or modification in the same object that caused the trigger to fire.
After Trigger: Executes after a record is saved to the database. Commonly used for creating or updating related records or sending notifications.
9. What are recursive triggers, and how do you avoid them?
Recursive Trigger: A trigger that calls itself repeatedly, potentially causing infinite loops.
Solution: Use static variables in an Apex class to prevent recursion:
public class TriggerHandler {
public static Boolean isTriggerExecuted = false;
}
10. What are Salesforce Governor Limits, and why are they important in triggers?
Governor limits are restriction set by Salesforce to ensure that Salesforce resources are shared efficiently in its cloud based environment.
These limits applies to various Salesforce operations such as – number of SOQL queries, DML operations, CPU time used in a single transaction and many more.
In case of Salesforce triggers, if any trigger exceeds these limits, then Salesforce will throw a runtime error and that transaction will fail.
11. What is a trigger framework?
A Trigger Framework in Salesforce is a structured approach to organize and manage Apex triggers.
It typically separates trigger logic into different layers, such as handler classes, to ensure clean, efficient, and reusable code.
The framework helps in controlling trigger execution and avoids common issues like recursion and duplicate logic.
12. Advantages of Trigger Framework
- Logic less trigger:
Keeps trigger logic separate from business logic by using handler classes. - Reusability:
Business logic can be reused across multiple triggers or processes. - Improved Maintainability:
Easier to maintain, debug, and extend the codebase as triggers grow in complexity. - Avoids Recursion:
Prevents infinite recursion by implementing checks and controls. - Scalability:
Supports bulk operations efficiently, adhering to Salesforce governor limits. - Consistency:
Ensures consistent coding standards and avoids redundant code.
- Logic less trigger:
By adopting a trigger framework, developers can write cleaner, scalable, and more efficient trigger code in Salesforce.
13. How do you handle errors in triggers?
Handling errors in triggers is crucial to ensure data integrity and a smooth user experience.
Here are 4 best practices for managing errors effectively in Salesforce triggers:
1. Use Try-Catch Blocks:
Wrap your DML operations or logic inside a try-catch block to catch and handle exceptions.
try {
insert newRecords;
} catch (DmlException e) {
System.debug('Error: ' + e.getMessage());
}
2. Add Custom Error Messages:
Use addError() to display meaningful error messages directly on specific records, preventing faulty records from being saved.
for (Account acc : Trigger.new) {
if (acc.Name == null) {
acc.addError('Account Name cannot be blank.');
}
}
3. Partial Success with Database Methods:
Use Database.insert or Database.update with the allOrNone=false option to handle partial failures and avoid transaction rollbacks.
Database.SaveResult[] results = Database.insert(accounts, false);
for (Database.SaveResult res : results) {
if (!res.isSuccess()) {
System.debug('Error: ' + res.getErrors()[0].getMessage());
}
}
4. Log Errors:
Store errors in a custom object (like Error_Log__c) for auditing and troubleshooting.
By following these practices, you can ensure your triggers handle errors gracefully, improve system reliability, and provide a better user experience.
14. Can you call a future method from a trigger?
Yes, you can call a future method from a trigger.
However, you can only from an After Trigger, as future methods run asynchronously and require the record to be committed to the database.
Use Case: After any DML operation, if you want to do a callout from Salesforce to an external system, then from your trigger you can call Future method for callout.
15. How do you use Trigger.isExecuting?
Trigger.isExecuting is a context variable in Salesforce that returns true when the current code is being executed as part of a trigger.
It helps developers identify whether the code is running within a trigger context or from another source, such as a batch job, Visualforce page, or API call.
When to Use Trigger.isExecuting?
- Conditional Execution:
Use Trigger.isExecuting to ensure certain code only runs when triggered by a trigger, preventing accidental execution from other contexts. - Debugging or Logging:
Identify when and where code is executing for better logging or debugging. - Trigger Context-Specific Logic:
Handle trigger-specific logic differently from logic called via controllers, batch jobs, or other Apex classes.
- Conditional Execution:
public class AccountHandler {
public static void processAccounts(List accList) {
if (Trigger.isExecuting) {
System.debug('Code is running inside a trigger.');
} else {
System.debug('Code is running outside of a trigger context.');
}
// Perform trigger-specific operations
if (Trigger.isExecuting && Trigger.isBefore) {
for (Account acc : accList) {
acc.Name = acc.Name + ' - Updated in Trigger';
}
}
}
}
Explanation
- Trigger.isExecuting ensures the code only runs in a trigger context.
- In the example, we check if the execution is within a trigger and handle before logic accordingly.
- If the method is called outside the trigger (e.g., from a Visualforce page or API), the debug log will indicate a different context.
16. What is a bulk trigger?
A bulk trigger in Salesforce is a trigger designed to handle multiple records (up to 200) efficiently in a single transaction.
It ensures operations like insert, update, or delete work for both single records and bulk operations, such as data loads or batch processes.
Key Point: Bulk triggers use loops, collections (e.g., lists, maps), and avoid SOQL/DML inside loops to adhere to governor limits.
17. How do you test a trigger in Salesforce?
To test a trigger in Salesforce, write an Apex test class that simulates the trigger’s operation using test data.
Steps to Test a Trigger:
- Create Test Data: Insert or update records needed to fire the trigger.
- Call DML Operations: Perform actions like insert, update, or delete to invoke the trigger.
- Assert Results: Use System.assert to verify expected outcomes.
- Use Test.startTest() and Test.stopTest(): Simulate governor limit scenarios and measure trigger performance.
@isTest
public class AccountTriggerTest {
@isTest static void testAccountTrigger() {
// Create test data
Account acc = new Account(Name = 'Test Account');
Test.startTest();
insert acc; // This will fire the trigger
Test.stopTest();
// Assertions
System.assertEquals('Test Account', acc.Name);
}
}
18. How do you write a trigger for a Many-to-Many Relationship?
A Many-to-Many relationship in Salesforce is achieved using a junction object, which connects two objects through master-detail or lookup relationships.
So, you need to write a trigger on the junction object to manage logic when records are created, updated, or deleted.
Steps to Write a Trigger for Many to Many Relationship
- Identify the Junction Object: This object links the two related objects.
- Trigger Context: Write the trigger on the junction object to handle insert, update, or delete operations.
- Handle Logic: Manage related records (e.g., calculations or updates) as needed.
19. Can a trigger update its own object?
Yes, we can write a trigger to update records in the same object.
But be cautious of Recursion and always use Before context if you are writing trigger to perform DML on same object. Use static variables to prevent infinite loops.
20. What are context-specific methods in triggers?
Context-specific methods in triggers are methods that provide information about the current trigger event and help control logic execution.
These methods are part of the Trigger class in Salesforce.
List of Context-Specific Methods:
- Trigger.isInsert – Returns true if the trigger is fired on insert.
- Trigger.isUpdate – Returns true if the trigger is fired on update.
- Trigger.isDelete – Returns true if the trigger is fired on delete.
- Trigger.isBefore – Returns true if the trigger is fired before the DML operation.
- Trigger.isAfter – Returns true if the trigger is fired after the DML operation.
- Trigger.isExecuting – Returns true if the current context is a trigger.
21. How do you integrate triggers with flows or workflows?
To integrate triggers with Flows or Workflows in Salesforce, follow these steps:
- Trigger Logic First:
Triggers execute before Flows and Workflows in the Order of Execution. - Call Flows Using DML:
Use a Record-Triggered Flow to respond to the record changes caused by a trigger.
For example, an after trigger updates a record → the Flow is triggered automatically. - Use Platform Events:
Triggers can publish Platform Events, which can then be consumed by Flows for asynchronous actions. - Workflow Field Updates:
If a Workflow updates a record, the trigger fires again (recursively), so implement recursion prevention logic in triggers. - Best Practice:
Design triggers to handle complex logic while using Flows or Workflows for declarative automation to keep the system scalable and maintainable.
- Trigger Logic First:
22. How do triggers handle roll-up summary fields?
Roll-up summary fields can only be created in a Master-Detail Relationship and CANNOT be directly updated using triggers.
However, if the relationship between two objects is a Lookup Relationship and you need a roll-up summary-like functionality on the parent object, you can achieve this using Apex triggers to calculate and update the required values.
23. Can you use Database.insert() in triggers?
Yes, we can use Database methods (like – Database.insert, database.update, database.upsert etc) in Salesforce triggers.
It is actually recommended to use Database methods for DML operations as they provide greater flexibility, especially with the allOrNone parameter, which helps handle errors more effectively during bulk insert or update operations.
24. What are common errors you have encountered in triggers ?
There can be multiple errors in Salesforce trigger if not written correctly following best practises:
Some of them which I have encountered are:
- Too Many SOQL Queries
- Mixed DML Operation:
- Too many DML statements
- Trigger Depth limit reached
- Governor limit errors
- Mixing Before and After logic
25. How do you ensure trigger best practices?
Following best practices while writing Apex triggers is crucial to avoid common errors mentioned above.
I recommend checking the post below, which briefly explains the best practices for writing efficient and error-free Salesforce triggers.
26. What is the importance of context variables in triggers?
Context variables in triggers are essential as they provide information about the current trigger event and allow developers to control the logic based on the operation.
They help identify:
- Trigger event:
(Insert, Update, Delete) using variables like Trigger.isInsert or Trigger.isUpdate. - Record states:
(new or old values) using Trigger.new and Trigger.old. - Execution context:
(before or after) using Trigger.isBefore or Trigger.isAfter.
- Trigger event:
By leveraging context variables, developers can write bulkified, efficient, and context-aware trigger logic.
27. Can a trigger call another trigger?
Yes, a trigger can call another trigger.
However, it should be avoided as much as possible to prevent performance issues.
28. What is the difference between Trigger.newMap and Trigger.oldMap?
Trigger.newMap
- Trigger.newMap contains map of IDs to new records (after changes) in insert and update triggers.
- Trigger.newMap is available in before update, after insert, and after update triggers.
Trigger.oldMap
- Trigger.oldMap contains map of IDs to old records (before changes) in update and delete triggers.
- Trigger.oldMap is Available in before update, after update, before delete, and after delete triggers.
Key Difference
Trigger.newMap contains the updated/new values, while Trigger.oldMap contains the original values of records.
29. How do you optimize SOQL queries in triggers?
To optimize SOQL queries in triggers:
- Avoid SOQL in Loops: Query records outside loops and store results in collections.
- Use Selective Queries: Retrieve only required fields to reduce data size.
- Filter with WHERE Clauses: Use indexed fields and specific conditions for efficient querying.
- Use Bulk Queries: Query all necessary records at once for bulk processing.
- Leverage Maps: Store query results in a Map for quick access by record IDs
Map accMap = new Map(
[SELECT Id, Name FROM Account WHERE Id IN :Trigger.newMap.keySet()]
);
This approach ensures your trigger adheres to governor limits and performs efficiently.
If you’d like to learn more about how to Optimise SOQL Statements in Apex, I highly recommend checking out the post below.
It provides a step-by-step guide on how to optimise SOQL queries in your Salesforce Triggers and Apex class.
30. How do triggers impact record locking?
Triggers can lead to record locking in Salesforce when multiple transactions attempt to update the same record simultaneously.
This impact is more noticeable during DML operations, especially when processing records in bulk.
What Happens:
When a trigger updates or inserts records, Salesforce locks the related records to prevent conflicts.
Causes of Locking Issues:
- Updating the same records in multiple processes simultaneously.
- Parent-child relationships causing cascading locks.
- Performing DML on related records (e.g., in after update triggers).
How to Avoid Locking Issues:
- Process records in small batches.
- Use SOQL queries efficiently to minimize updates.
- Avoid unnecessary DML operations within loops.
- For large operations, use asynchronous Apex like Queueable or Batch Apex.