Sharing is caring!
This Salesforce Blog is a developer’s experience in the Journey of Force.com development and customization. The problems faced by a day to day developer and the mistakes committed by them can sometimes be interesting and useful to a wide range of developers and administrators.
So let’s start the epic!!
1. DO NOT HARDCODE!!!
Once upon a time I was developing on a VF page and provided a link to a report(Our Standard Salesforce Reports in Visualforce Page:
So I hardcoded the URL for the report as a link in my VF page. The URL was working fine in the sandbox and I was happy. Once I was done with development I migrated my changes to the Production environment, Finally when I tested the application on the website I was unable to see the report on clicking the link.
But I got to know later that I cannot modify the apex class in production environment and I needed to fix it ASAP so it was all a big mess!
After scrutinizing the snag, I found that I had hardcoded the URL for my report and since the environment has changed URL had stopped working.
So I finally figured it out using the concept of dynamic URLs and used some code snippet like below:
“URL.getSalesforceBaseUrl().toExternalForm()+’/’+reportId”
Final Verdict: > DO NOT HARDCODE!!!
2. Avoid SOQL Errors
While Developing has you encountered errors such as “System.LimitException: Too many SOQL queries: 101”?
This error System.LimitException : Too many SOQL queries: 101 is due to the fact, you are hitting on governor limit.
Our esteemed Governor limits says that you can run total 100 SOQL queries in a context and you are hitting the limit.
After a thorough study on the same, I found that all the triggers fired will be counted in a single context or call. We need to ensure that the total number of SOQL fired should be less than 100.
In order to pass this, Many times I changed my code in such a way that SOQL fired must be less than 100.
Sometimes I have also preferred if (only we need to change the context) using @future annotation when I was required to run the code asynchronously.
I made sure always that the SOQL query I use should not be inside the for loop.
There are certain best practices which you would have to follow to avoid this error (to avoid hitting governor limit).
http://wiki.developerforce.com/page/Best_Practice:_Avoid_SOQL_Queries_Inside_FOR_Loops
http://salesforcedeveloperblog.blogspot.com/2011/05/best-practices-of-triggers.htm http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_bestpract.htm
http://wiki.developerforce.com/page/Apex_Code_Best_Practices https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_gov_limits.htm
Always follow the above practices to make sure you stay smiling at your workplace.
The challenging part is that one cannot increase the governor limit and can only follow best practices.
3. Streamline Multiple Triggers on the same Object
So here Is one more tricky situation:
Once I was working on a requirement (in short) on the esteemed object Case to assign the account manager automatically. So I wrote a trigger which was “Before Insert”.
I found that sometimes the account manager assigned was as expected and sometimes NOT!!
I was Bewildered !!
Like Always I started digging out checking to debug logs, manual testing etc.
Finally, Debug log was a ‘Maseeha’ telling me that I do have two more triggers with “Before Insert “ due to which system was unable to recognize the order of execution.
Probably those codes were drafted by some other developers( of course my current and previous colleagues).
I sat with them and finally came up with a single trigger with the same event on the object.
So in practice, Avoid multiple triggers with the same event on an object because it may discommode you at times.
4. Bulkify Your Code
So in the initial days of my Salesforce Development career, I faced something very terrible and good learning of course for me.
Let’s start with giving you some glimpse on my poorly written code that only handles one record :
trigger BeforeInsert_Account on Account (before insert)
{
//This only handles the first record in the Trigger.new collection
//But if more than 1 Account initiated this trigger, those additional records
//will not be processed
Account objAccount= Trigger.new[0];
List contacts = [select id, salutation, firstname, lastname, email from Contact where accountId = :acct.Id];
//and something something……
}
I tested the trigger and it worked fine and I was done by my job and then suddenly one day trigger hit the governor limits.
Like always I was bewildered. Got to know that one of my sweet colleagues has written a batch apex to insert the Accounts and this was the whole sole reason.
Since I couldn’t ask my sweet colleague to undo the batch class, I need to do something.
After digging, I found that if a batch of records invokes my Apex code, all of those records need to be processed as a bulk, which hits governor limits.
And the issue was that only one Account record was handled because the code explicitly accesses only the first record in the Trigger.new collection by using the syntax Trigger.new[0]. Instead, the trigger should properly handle the entire collection of Accounts in the Trigger.new collection.
Here is a sample of how I handled all incoming records from batch:
trigger BeforeInsert_Account on Account (before insert)
{
List accountNames = new List{};
//Loop through all records in the Trigger.new collection
for(Account a: Trigger.new)
{
//Something something…
}
}
Notice how this revised version of the code iterates across the entire Trigger.a new collection with a for the loop. Now if this trigger is invoked with a single Account or up to 200 Accounts, all records will be properly processed.
So always put down strategy to write bulkified code. Make it as practice, though it will be not easy but good for long terms!!
5. Follow General Design Guidelines for Application Performance
As per my experience in designing Visualforce, you may develop a very rich UI with nice pop-ups and images but when the users start using it, it becomes nettlesome for them to click or navigate to buttons.
I have written these general guidelines to avoid performance impacts:
- Always design pages around specific tasks, with a sensible workflow and navigation between tasks. The DOTS should be connected everywhere.
- Never overload pages with functionality and data. Visualforce pages with unbounded data or a large number of components, rows, and fields have poor ability and performance, and they risk hitting governor limits for view state, heap size, record limits, and total page size.
- Always try to push back on requests to include non-essential functionality.
- Must Build prototypes to validate concerns.
References:
Read Also: 7 Checkpoints for Salesforce Developer
Akshay Dhiman
Chief Technical Officer
Akshay Dhiman, the CTO of Cloud Analogy, has been a standout and successful Salesforce Platform Developer for years. He has a rich experience in Salesforce Integration, JavaScript, APEX, VisualForce, Force.com Sites, Batch Processing, Lightning, PHP, C++, Java, NodeJs, ReactJs, Angular 8, GraphQL, React Native, Web Technology, and jQuery.Hire the best Salesforce Development Company. Choose certified Salesforce Developers from Cloud Analogy now.
This is quite a nice article.
Hi Claudia, Appreciate your kind words. We are glad you like it.
Thanks 🙂