Tuesday, December 3, 2024

Salesforce Apex Trigger interview questions with answers and including scenario-based questions.

 Salesforce Apex Trigger interview questions with answers, including scenario-based questions. These questions are categorized into beginner, intermediate, and advanced levels.

Beginner-Level Questions

1. What is an Apex Trigger?

  • Answer:
    An Apex Trigger is a piece of code executed before or after certain database events like INSERT, UPDATE, DELETE, or UNDELETE on Salesforce records. Triggers allow custom actions to occur when a record is manipulated.

2. What are the types of triggers in Salesforce?

  • Answer:
    • Before Triggers: Execute before a record is saved to the database. Used for validation or setting default values.
    • After Triggers: Execute after a record is saved to the database. Used for actions like sending emails or calling external APIs.

3. What are Trigger Context Variables?

  • Answer:
    Trigger context variables provide runtime information about the trigger's execution. Common variables include:
    • Trigger.new: Contains new versions of the records being modified.
    • Trigger.old: Contains old versions of the records (for UPDATE or DELETE).
    • Trigger.isInsert, Trigger.isUpdate, Trigger.isDelete, etc.: Boolean flags for trigger operations.

4. What are Governor Limits in Salesforce?

  • Answer:
    Salesforce imposes limits to ensure efficient use of resources. Examples include:
    • SOQL Queries: 100 per transaction.
    • DML Statements: 150 per transaction.
    • Heap Size: 6 MB (synchronous) / 12 MB (asynchronous).

Intermediate-Level Questions

5. Can you invoke a trigger on a custom object?

  • Answer:
    Yes, triggers can be created on custom objects. The syntax is the same as for standard objects, e.g.,
    apexcode
    trigger CustomObjectTrigger on CustomObject__c (before insert, after insert) { // Code logic here }

6. How do you prevent recursive trigger execution?

  • Answer:
    Recursive triggers can be controlled using a static Boolean variable in an Apex class:
    apex code
    public class TriggerHelper { public static Boolean isTriggerExecuted = false; } trigger AccountTrigger on Account (before insert) { if (!TriggerHelper.isTriggerExecuted) { TriggerHelper.isTriggerExecuted = true; // Trigger logic } }

7. What is the difference between Trigger.new and Trigger.old?

  • Answer:
    • Trigger.new: Contains the new version of records being inserted/updated. It’s available in INSERT and UPDATE triggers.
    • Trigger.old: Contains the old version of records. It’s available in UPDATE and DELETE triggers.

8. Scenario: Write a trigger to prevent deletion of an Account if it has related Contacts.

  • Answer:
    apex code
    trigger PreventAccountDeletion on Account (before delete) { for (Account acc : Trigger.old) { if ([SELECT COUNT() FROM Contact WHERE AccountId = :acc.Id] > 0) { acc.addError('Cannot delete account with related contacts.'); } } }

9. What is the purpose of the addError method in triggers?

  • Answer:
    The addError method prevents DML operations on a record and displays a custom error message. It’s used for validations and ensuring data integrity.

Advanced-Level Questions

10. How do you bulkify a trigger?

  • Answer:
    Bulkification ensures triggers handle multiple records efficiently. For example:
    • Avoid SOQL or DML statements inside loops.
    • Use collections like List or Map for batch processing. Example:
    apex code trigger UpdateOpportunities on Account (after update) { Set<Id> accountIds = new Set<Id>(); for (Account acc : Trigger.new) { accountIds.add(acc.Id); } List<Opportunity> opportunities = [SELECT Id, AccountId FROM Opportunity WHERE AccountId IN :accountIds]; for (Opportunity opp : opportunities) { opp.StageName = 'Updated'; } update opportunities; }

11. Scenario: Create a trigger to automatically update an Opportunity's StageName to "Closed Won" when the related Account's Type is changed to "Customer".

  • Answer:
    apex code trigger UpdateOpportunitiesOnAccountChange on Account (after update) { Set<Id> accountIds = new Set<Id>(); for (Account acc : Trigger.new) { if (acc.Type == 'Customer' && acc.Type != Trigger.oldMap.get(acc.Id).Type) { accountIds.add(acc.Id); } } if (!accountIds.isEmpty()) { List<Opportunity> oppsToUpdate = [SELECT Id, StageName FROM Opportunity WHERE AccountId IN :accountIds]; for (Opportunity opp : oppsToUpdate) { opp.StageName = 'Closed Won'; } update oppsToUpdate; } }

12. What are the limitations of Apex Triggers?

  • Answer:
    • Cannot make direct callouts to external services.
    • Subject to governor limits (SOQL, DML, CPU time, etc.).
    • Cannot run asynchronously.

13. Scenario: Write a trigger to calculate and update a custom field Total_Contacts__c on Account whenever a Contact is added, updated, or deleted.

  • Answer:
    apex code trigger UpdateContactCount on Contact (after insert, after update, after delete, after undelete) { Set<Id> accountIds = new Set<Id>(); if (Trigger.isInsert || Trigger.isUpdate || Trigger.isUndelete) { for (Contact con : Trigger.new) { accountIds.add(con.AccountId); } } if (Trigger.isDelete) { for (Contact con : Trigger.old) { accountIds.add(con.AccountId); } } if (!accountIds.isEmpty()) { List<Account> accountsToUpdate = [SELECT Id, Total_Contacts__c, (SELECT Id FROM Contacts) FROM Account WHERE Id IN :accountIds]; for (Account acc : accountsToUpdate) { acc.Total_Contacts__c = acc.Contacts.size(); } update accountsToUpdate; } }

14. Scenario: How would you design a trigger framework for large-scale Salesforce implementations?

  • Answer:
    A trigger framework organizes triggers to follow best practices. Key elements include:

    • Handler Class: Use a separate class to handle logic.
    • One Trigger per Object: Avoid multiple triggers on the same object.
    • Trigger Context Handling: Manage before and after contexts separately.

    Example:

    public class AccountTriggerHandler { public static void handleBeforeInsert (List<Account> newAccounts) { // Logic here } public static void handleAfterUpdate (Map<Id, Account> oldMap, List<Account> updatedAccounts) { // Logic here } } trigger AccountTrigger on Account (before insert, after update) { if (Trigger.isBefore && Trigger.isInsert) { AccountTriggerHandler.handleBeforeInsert(Trigger.new); } else if (Trigger.isAfter && Trigger.isUpdate) { AccountTriggerHandler.handleAfterUpdate(Trigger.oldMap, Trigger.new); } }

No comments:

Post a Comment