โ† Back to list

๐Ÿš€ Top Apex Trigger Scenarios

Real Use Cases + How to Solve Them + Interview Questions

Zerotozenkai by Sneha Kate ยท 2026-05-07 08:51 ยท 266 claps ยท 5.2 min read
#salesforce #salesforce-productivity #salesforce-development #salesforce-architect #salesforce-tools
Open on Medium โ†—
Wiki topics: CRM ยท Email & CRM โฑ๏ธ ยท Productivity ๐Ÿ›๏ธ ยท Architecture

๐Ÿš€ Top Apex Trigger Scenarios

Real Use Cases + How to Solve Them + Interview Questions

๐Ÿ”ฅ Why This Blog Matters

Most developers know what a trigger is.

But in interviews, youโ€™re not asked: -> โ€œWhat is a trigger?โ€

Youโ€™re asked: -> โ€œHow do you handle real business scenarios using triggers?โ€

Thatโ€™s where things get tricky.

From my experience, writing a trigger is not the hard part โ€” handling real-world requirements cleanly and efficiently is what actually matters.

โšก Scenario 1: Prevent Duplicate Records

-> When This Happens

Creating Accounts / Contacts / Leads Business wants to avoid duplicate data

* Problem

Duplicate records get created manually or via integrations.

*Solution

trigger PreventDuplicateAccount on Account (before insert) {

Set<String> names = new Set<String>();

for (Account acc : Trigger.new) { if (acc.Name != null) { names.add(acc.Name); } }

Map<String, Account> existingAccounts = new Map<String, Account>();

for (Account acc : [ SELECT Id, Name FROM Account WHERE Name IN :names ]) { existingAccounts.put(acc.Name, acc); }

for (Account acc : Trigger.new) { if (existingAccounts.containsKey(acc.Name)) { acc.addError('Duplicate Account Name not allowed'); } } }

๐ŸŽฏ Key Insight

Use Set and Map instead of nested loops for better performance

โšก Scenario 2: Update Child Records When Parent Changes

-> When This Happens

Account is updated

Related records (Contacts) need updates

* Problem

Child records become inconsistent.

*Solution

trigger UpdateContacts on Account (after update) {

Set<Id> accountIds = new Set<Id>();

for (Account acc : Trigger.new) { Account oldAcc = Trigger.oldMap.get(acc.Id);

if (acc.Industry != oldAcc.Industry) { accountIds.add(acc.Id); } }

List<Contact> contactsToUpdate = new List<Contact>();

if (!accountIds.isEmpty()) { for (Contact con : [ SELECT Id, AccountId FROM Contact WHERE AccountId IN :accountIds ]) { con.Description = 'Updated due to Account Industry change'; contactsToUpdate.add(con); } }

if (!contactsToUpdate.isEmpty()) { update contactsToUpdate; } }

๐ŸŽฏ Key Insight

Always check if a field actually changed before processing

โšก Scenario 3: Validate Business Rules

->When This Happens

Before inserting or updating records Business rules must be enforced

* Problem

Invalid data gets stored.

* Solution

trigger ValidateOpportunity on Opportunity (before insert, before update) {

for (Opportunity opp : Trigger.new) { if (opp.Amount == null || opp.Amount <= 0) { opp.addError('Amount must be greater than 0'); } } }

๐ŸŽฏ Key Insight

Use before triggers for validations (no DML needed)

โšก Scenario 4: Create Related Records Automatically

-> When This Happens

Create child records when parent is created

* Problem

Manual process leads to inconsistency.

* Solution

trigger CreateContact on Account (after insert) {

List<Contact> contacts = new List<Contact>();

for (Account acc : Trigger.new) { contacts.add(new Contact( LastName = acc.Name, AccountId = acc.Id )); }

if (!contacts.isEmpty()) { insert contacts; } }

๐ŸŽฏ Key Insight

Use after insert when record Id is required

โšก Scenario 5: Prevent Deletion of Important Records

->When This Happens

Prevent deletion of records with dependencies

* Problem

Important data gets deleted.

* Solution

trigger PreventDeleteAccount on Account (before delete) {

Set<Id> accountIds = new Set<Id>();

for (Account acc : Trigger.old) { accountIds.add(acc.Id); }

Map<Id, Integer> oppCountMap = new Map<Id, Integer>();

for (AggregateResult ar : [ SELECT AccountId accId, COUNT(Id) count FROM Opportunity WHERE AccountId IN :accountIds GROUP BY AccountId ]) { oppCountMap.put((Id)ar.get('accId'), (Integer)ar.get('count')); }

for (Account acc : Trigger.old) { if (oppCountMap.containsKey(acc.Id)) { acc.addError('Cannot delete account with related opportunities'); } } }

๐ŸŽฏ Key Insight

Use aggregate queries to avoid SOQL inside loops

โšก Scenario 6: Avoid Recursive Triggers

-> When This Happens

Trigger updates same object again

* Problem

Infinite loop or governor limit error

* Solution

public class TriggerControl { public static Boolean isFirstRun = true; }

trigger AccountTrigger on Account (after update) {

if (!TriggerControl.isFirstRun) return;

TriggerControl.isFirstRun = false;

// logic here }

๐ŸŽฏ Key Insight

Always control recursion when updating same object

โšก Scenario 7: Populate Fields Automatically

-> When This Happens

Business wants default values

* Problem

Users miss important fields

* Solution

trigger DefaultAccountRating on Account (before insert, before update) {

for (Account acc : Trigger.new) { if (acc.AnnualRevenue != null && acc.AnnualRevenue > 1000000) { acc.Rating = 'Hot'; } else { acc.Rating = 'Warm'; } } }

๐ŸŽฏ Key Insight

Use before trigger to update fields without extra DML

โšก Scenario 8: Restrict Updates Based on Condition

->When This Happens

Lock records after a stage

* Problem

Users modify finalized records

*Solution

trigger RestrictOpportunityUpdate on Opportunity (before update) {

for (Opportunity opp : Trigger.new) { Opportunity oldOpp = Trigger.oldMap.get(opp.Id);

if (oldOpp.StageName == 'Closed Won' && opp.StageName != oldOpp.StageName) { opp.addError('Closed Won Opportunities cannot be modified'); } } }

๐ŸŽฏ Key Insight

Compare old vs new values to control updates

โšก Scenario 9: Cascade Delete (Custom Cleanup)

-> When This Happens

Custom lookup relationships

* Problem

Orphan records remain

* Solution

trigger DeleteRelatedRecords on Account (before delete) {

Set<Id> accountIds = new Set<Id>();

for (Account acc : Trigger.old) { accountIds.add(acc.Id); }

List<Custom_Object__c> recordsToDelete = [ SELECT Id FROM Custom_Objectc WHERE Accountc IN :accountIds ];

delete recordsToDelete; }

๐ŸŽฏ Key Insight

Needed when cascade delete is not available

โšก Scenario 10: Callout from Trigger (Async)

-> When This Happens

Need to call external API

*Problem

Callouts not allowed directly in trigger

*Solution

public class AccountCalloutService {

@future(callout=true) public static void sendData(Set<Id> accountIds) { // callout logic } }

trigger AccountTrigger on Account (after insert) {

Set<Id> ids = new Set<Id>();

for (Account acc : Trigger.new) { ids.add(acc.Id); }

AccountCalloutService.sendData(ids); }

๐ŸŽฏ Key Insight

Use async processing for external calls

โšก Scenario 11: Prevent Duplicate Using Multiple Fields

-> When This Happens

Unique combination required

* Problem

Standard duplicate rules are not enough

* Solution

trigger PreventDuplicateContact on Contact (before insert) {

Set<String> keys = new Set<String>();

for (Contact con : Trigger.new) { keys.add(con.Email + '-' + con.Phone); }

for (Contact existing : [ SELECT Email, Phone FROM Contact ]) { String key = existing.Email + '-' + existing.Phone;

for (Contact con : Trigger.new) { if ((con.Email + '-' + con.Phone) == key) { con.addError('Duplicate Contact'); } } } }

๐ŸŽฏ Key Insight

Custom logic helps when business rules are complex

โš”๏ธ Best Practices

  • One trigger per object
  • Avoid SOQL/DML inside loops
  • Use Sets and Maps
  • Handle bulk records
  • Write test classes

๐Ÿง  Interview Questions

Q1: How do you make triggers bulk-safe?

-> Use collections and avoid SOQL/DML inside loops

Q2: How do you detect field changes?

-> Compare Trigger.new with Trigger.oldMap

Q3: Can we call external APIs from triggers?

-> No, use async Apex (future/queueable)

Q4: How do you avoid recursion?

-> Use static flags or control logic

Q5: What causes governor limit issues?

-> SOQL/DML inside loops and unoptimized code

Q6: How do you handle large data volumes?

-> Bulkification and efficient queries

Q7: What is a common mistake developers make?

-> Writing logic for single record but not handling bulk

๐Ÿ’ก Final Thought

In real projects, you rarely deal with just one scenario.

Most of the time, multiple requirements come together โ€” and thatโ€™s where clean design and proper trigger handling really help.

๐Ÿ Takeaway

-> Itโ€™s not about writing a trigger -> Itโ€™s about writing a trigger that works at scale

๐Ÿ”ฅ Whatโ€™s Next?

-> LWC + Apex Integration Scenarios (Real Project Examples)

๐Ÿš€ Connect With Me

Hi, Iโ€™m Sneha Kate

๐Ÿ“Œ Follow for more content on:

  • Salesforce Development
  • Apex & LWC
  • Salesforce Integrations
  • Slack Automation
  • Agentforce
  • Copado & DevOps
  • CI/CD Pipelines
  • Real-World Salesforce Engineering

๐Ÿ’ก I regularly share practical implementations, interview scenarios, deployment concepts, and real project learnings based on what we are building and exploring together.

๐Ÿ”— LinkedIn : Sneha Kate

๐Ÿ“ง Email:

๐Ÿ’ฌ Feel free to ask questions or connect with me on LinkedIn.

๐ŸŒฑ We grow faster when we grow together.

Salesforce #Apex #Triggers #InterviewPrep #TechCareers


๋ฉ”ํƒ€๋ฐ์ดํ„ฐ
post_id
aea358f3b107
slug
top-apex-trigger-scenarios-aea358f3b107
url
https://medium.com/@zerotozenkai20/top-apex-trigger-scenarios-aea358f3b107
canonical_url
https://medium.com/@zerotozenkai20/top-apex-trigger-scenarios-aea358f3b107
author_url
https://medium.com/@zerotozenkai20
status
ok
fetched_at
2026-06-09 15:37:30