You can handle this using an after-update Opportunity trigger + Queueable Apex. First, collect the unique Account IDs where the Opportunity changes to Closed Won, then pass those IDs to a single Queueable job.
In the Queueable, query the related Accounts and Opportunities, determine the latest Closed Won Opportunity for each Account, and update the Account Description in one bulk DML operation.
This approach avoids SOQL/DML inside loops and handles bulk updates safely. Salesforce recommends bulkifying both SOQL and DML operations.
Also, use a Set<Id> for Account IDs to ensure the same Account is processed only once.
Code:
trigger OpportunityTrigger on Opportunity (after update) {
Set<Id> accountIds = new Set<Id>();
for (Opportunity opp : Trigger.new) {
Opportunity oldOpp = Trigger.oldMap.get(
);
if (opp.StageName == 'Closed Won' &&
oldOpp.StageName != 'Closed Won' &&
opp.AccountId != null) {
accountIds.add(opp.AccountId);
}
}
if (!accountIds.isEmpty()) {
System.enqueueJob(new UpdateAccountDescriptionQueueable(accountIds));
}
}
Then the Queueable can query the latest Closed Won Opportunity per Account and perform one bulk update on the Accounts.
One important consideration: because the requirement is “latest Opportunity Name”, don't simply use the Opportunity from Trigger.new; if multiple Opportunities for the same Account are updated in the same transaction or an older Closed Won Opportunity already exists, the Queueable should determine the latest record from the database.
This follows Salesforce's bulk-processing guidance and keeps the trigger lightweight.
Hope This Helps!!
I’m currently working on integrating AI features into a ticketing system for a client. The main focus areas are:
- Summarizing support tickets automatically
- Finding similar/repeated issues
- Improving overall ticket analysis and resolution flow
I want to build this properly using Salesforce AI capabilities (Einstein / Agentforce / AI-related tools), but I’m a bit confused about which Trailhead trails/modules I should focus on first to get a solid understanding of AI in this context.
If anyone has experience with similar implementations or can recommend the best learning path/resources, I’d really appreciate the guidance.
#Agentforce #Salesforce Developer #Artificial Intelliegnce #Apex
9月8日 05:55 Hi Aakash,
For an AI-based ticketing system in Salesforce, I would start with Service Cloud and Case Management, then learn AI Summary and Prompt Builder to understand how Salesforce can automatically summarize support tickets and generate useful insights. After that, focus on Knowledge, Similar Cases, and Case Retriever so the system can identify repeated or related issues from historical tickets and use previous solutions as context. Next, learn Service Assistant and Agentforce for Service to understand how AI can analyze cases, recommend resolutions, retrieve relevant Knowledge articles, and assist support agents. Finally, learn how to connect these capabilities with Flow and Apex so the entire ticket analysis and resolution process can be automated. For your use case, the most important areas to focus on are Prompt Builder, Similar Cases/Case Retriever, Service Assistant, Knowledge, and Agentforce, as these will help you build an end-to-end AI-powered ticketing solution.
Welcome to the Salesforce Developers Trailblazer Community — We Build What's Next
Updated: April 2026
You're part of a global community of 30,000+ Salesforce developers — from those writing their first #Apex class to those architecting multi-agent systems. Whatever brought you here, you belong here.
Right now, the most exciting thing happening in our ecosystem is Agentic #AI — and developers are at the centre of it. This post is your launchpad.
🚀 Get Hands-On with #Agentforce
The best way to understand agentic AI is to build with it:
- Register for upcoming Agentforce NOW events — AMAs, codeLives, and workshops where you learn directly from Salesforce experts and ship real code.
- Check out the new AgentExchange — a unified marketplace that brings together AppExchange, Slack Marketplace, and the Agentforce partner ecosystem.
- The Salesforce Developer Edition just got a major upgrade — every org now includes Agentforce Vibes IDE, Agentforce Vibes with Claude Sonnet 4.5, and Salesforce-hosted MCP Servers. A complete AI-assisted development environment, free.
📦 Post-#TDX26 Repos Every Developer Should Bookmark
Fresh from TrailblazerDX 2026, these 3 open-source repositories are where the community is building right now:
- Agent Script — The complete Agent Script language: parsing, linting, Language Server Protocol, UI — all open source. Dig in.
- Agentforce Vibes Skills Library — A curated skills library optimised for building Apex, LWC, Agentforce and more. If you're building agents, start here.
- Salesforce MCP Hosted Servers — Connect AI assistants like Claude and ChatGPT securely to your Salesforce logic and assets via hosted MCP servers.
- Salesforce Multi-Framework Recipes Sample App — Code examples for building modern web apps on Salesforce using React with Salesforce Multi-Framework. Dig in.
📚 Level Up: Learning Paths for Every Stage
Whether you're deepening your platform fundamentals or going all-in on agentic AI:
- Agentforce Decoded — YouTube series breaking down how Agentforce actually works
- Agentforce Developer Center — Your hub for all things Agentforce development
- Developer Beginner → Intermediate → Advanced trails — the classic progression, still essential
- Get Started as a Developer Quest — Earn points while building real skills
- Salesforce Developer Careers Page (recently refreshed!) — Explore opportunities and skills for every type of Salesforce developer
🎙️ Stay Connected & Keep Learning
- Salesforce Developers Blog — technical deep-dives, announcements, and how-tos
- Developer Newsletter — the best of developer content, straight to your inbox
- Monthly Ask Me Anything sessions — bring your questions to Salesforce product experts
🌎 Find Your People
- Find your local Salesforce Developer meetup — in-person community, networking, and career growth
- Salesforce MVPs — connect with community leaders and experts recognised for their contributions to the ecosystem
- Salesforce Developers on LinkedIn | on X
Have suggestions for resources or content? Drop them in the comments below — this community is built by all of us.
9月6日 09:21 Great introduction to the Salesforce Developers community. Agentforce and agentic AI are opening up some really interesting opportunities for developers, especially with the new Developer Edition features. I’m looking forward to exploring Agentforce Vibes and seeing how developers are using these tools in real-world projects.
In Apex, what happens when you assign one sObject variable to another and modify it? Why?
#Apex
9月4日 05:44 When one sObject variable is assigned to another, both variables refer to the
same sObject instance
in memory.
For example:
Account acc1 = new Account(Name = 'Original');Account acc2 = acc1;acc2.Name = 'Updated';System.debug(acc1.Name); // Updated
Here, changing acc2.Name also changes acc1.Name because both variables reference the same Account object.
So, assigning an sObject variable does not create a new copy
of the record; it creates another reference to the same object.
Hope This Helps!!
9月4日 05:48 Yes, a trigger can perform DML on the same object, but it depends on the trigger context.
For example, in an after update Account trigger:
trigger AccountTrigger on Account (after update) { for (Account acc : Trigger.new) { acc.Description = 'Updated'; } update Trigger.new;}This update causes the Account trigger to fire again, which can lead to recursive execution and eventually a Maximum trigger depth exceeded error.
Also, in a before trigger, we normally modify Trigger.new directly without performing DML, because Salesforce automatically saves those changes as part of the original transaction.
So the best practice is: avoid unnecessary DML on the same records and use appropriate recursion-control logic when same-object updates are required.
Hope This Helps!!.
Can someone explain what will happen when this Apex code runs? Will it update the Account successfully, or throw an error? Why?
Account acc = [
SELECT Id, Name
FROM Account
LIMIT 1
];
acc.Name = 'Updated Account';
List<Account> accounts = new List<Account>{ acc };
for (Account a : accounts) {
a.Name = 'Final Account';
}
update acc;
update accounts;Will both update statements execute successfully
9月4日 05:39 The first update acc; will execute successfully.
acc and accounts[0] reference the same Account record. The loop changes the Name to 'Final Account', so the first update saves 'Final Account'
.
The second update accounts; will also execute successfully because it is a separate DML statement containing only one record. The Duplicate id in list error occurs when the same record ID appears multiple times in the same list being updated, not simply because the record is updated twice in separate DML statements.
So, the final Account Name will be 'Final Account'.
For Reference: Salesforce Apex DML documentation.
Hope This Helps!!.
Hi Everyone,
I’m working on a scenario where an Opportunity trigger updates the related Account
, and an Account trigger in turn performs some additional updates.
What would be the best approach to prevent trigger recursion
while keeping the solution bulkified and scalable? Would a static variable-based approach be sufficient, or is there a better Trigger Handler pattern for managing this?
Looking forward to your recommendations and real-time implementation approaches.
Thanks!
#Salesforce #Salesforce Developer #Apex #Trailhead
9月4日 04:37 Best practice is a Trigger Handler pattern with controlled recursion, rather than relying only on a static Boolean.
- Keep triggers thin and move logic into handler/service classes.
- Use a static Set<Id> to track records already processed in the current transaction.
- Keep all logic bulkified—use collections and avoid SOQL/DML inside loops.
- Add clear entry conditions so updates only happen when relevant fields actually change.
A static Boolean can work for simple cases, but a
Set<Id> + Handler patternis more scalable for complex automation.
Hi Everyone,
I’m working with bulk DML operations in Apex and want to understand the practical difference between using standard DML statements and Database methods with allOrNone = false.
In a real project, when would you prefer Database.insert(records, false) over a normal insert records statement? What are the best practices for handling and logging failed records using Database.SaveResult?
Thanks in advance!
#Trailhead #Apex #Salesforce Developer
9月4日 04:38 @deeFor real projects, Database.insert(records, false) is useful when you want partial success—one failed record should not prevent valid records from being inserted.
Database.SaveResult[] results = Database.insert(records, false);
for (Integer i = 0; i < results.size(); i++) {
if (!results[i].isSuccess()) {
for (Database.Error err : results[i].getErrors()) {
System.debug(
'Failed Record: ' + records[i].Id +
' | Error: ' + err.getMessage()
);
}
}
}
Use normal insert when the entire operation should succeed or fail together.
Use Database.insert(records, false) for integrations, data loads, or batch processing where you want successful records saved while capturing failures for logging/reprocessing.
Best practice: always process SaveResult[] and log the record ID, status code, and error message for failed records.
We need to find Accounts that have Contacts whose Department is "IT", and print the Account Name along with the number of IT Contacts.
I tried this:
for (Account acc : [
SELECT Id, Name, (SELECT Id, Name, Department FROM Contacts)
FROM Account
]) {
Integer count = 0;
for (Contact con : acc.Contacts) {
if (con.Department == 'IT') {
count++;
}
}
System.debug(acc.Name + ' → IT Contacts: ' + count);
}
My question:
Why is acc.Contacts available inside the outer loop even though we didn't execute a separate SOQL query for Contacts?
Also, what happens if an Account has a very large number of Contacts? Is there a better/bulk-safe approach than using the nested loop
?
#Apex #Salesforce Developer
9月3日 16:47 Hi @Rohit .,
acc.Contacts is available because the query uses a Parent-to-Child Relationship Query:
SELECT Id, Name, (SELECT Id, Name, Department FROM Contacts)FROM Account
The child Contacts are retrieved as part of the same SOQL query and stored in the acc.Contacts relationship collection. Therefore, no separate SOQL query is required inside the loop.
Regarding a large number of Contacts, the nested loop is valid, but retrieving every Contact just to count IT Contacts may be inefficient. If we only need the count, an Aggregate SOQL query
with COUNT() and GROUP BY AccountId would be more efficient because the database performs the counting instead of Apex.
So, use the relationship query when you need to process Contact records; use Aggregate SOQL when you only need counts/statistics
.
Hope this help !!.
2023年5月30日 17:29 Hello Abhishek ,EmailMessage can be updated only when it's in the Draft status.Update() is supported when an email record is in Draft status, and IsPrivateDraft is false. It is also supported if Status and IsPrivateDraft are true and CreatedBy is associated with the current user. When the email record status is not in Draft status, the IsExternallyVisible field and custom fields only can be updated.Reference -> https://salesforce.stackexchange.com/questions/312390/receiving-illegal-operation-error-on-emailmessage-update-from-contentdocumentlinHope this helps !Thank you.