Close Menu
SalesforceCodex
    Facebook X (Twitter) Instagram
    Trending
    • Unlock the Power of Vibe Coding in Salesforce
    • How to Implement Dynamic Queueable Chaining in Salesforce Apex
    • How to Implement Basic Queueable Chaining in Salesforce Apex
    • How to Suppress PMD Warnings in Salesforce Apex
    • Top 10 PMD Issues Salesforce Developers Should Focus on in Apex
    • How to Use Graph API for Outlook-Salesforce Connection
    • Enhancing Performance with File Compression in Apex
    • Salesforce Spring ’25 Release: Top Flow Enhancements You Need to Know
    Facebook X (Twitter) Instagram
    SalesforceCodex
    Subscribe
    Thursday, May 8
    • Home
    • Architecture
    • Salesforce
      • News
      • Apex
      • Integration
      • Books Testimonial
    • Questions
    • Certification
      • How to Prepare for Salesforce Integration Architect Exam
      • Certification Coupons
    • Integration Posts
    • Downloads
    • About Us
      • Privacy Policy
    SalesforceCodex
    Home»Salesforce»Apex»Top 10 PMD Issues Salesforce Developers Should Focus on in Apex

    Top 10 PMD Issues Salesforce Developers Should Focus on in Apex

    Dhanik Lal SahniBy Dhanik Lal SahniFebruary 28, 2025No Comments6 Mins Read
    Facebook Twitter Pinterest LinkedIn Tumblr Email
    Top 10 PMD Issues
    Share
    Facebook Twitter LinkedIn Pinterest Email

    PMD (Programming Mistake Detector) is a static code analysis tool that helps Salesforce developers identify potential code quality, performance, and security issues in Apex. While PMD can detect numerous issues, not all are equally critical. This article will discuss the top 10 PMD issues that every Salesforce developer should focus on while writing Apex code.

    Fixing these issues will improve code quality, performance, maintainability, and security.

    1. Avoid SOQL Queries Inside Loops

    This is the most critical issue in Salesforce Apex. While writing code, developers execute code with a limited set of records. So sometimes they don’t face issues even queries written in the loop.

    Running SOQL queries inside a loop can cause governor limit violations. Salesforce enforces a limit of 100 SOQL queries per transaction, and if exceeded, the transaction will fail.

    Bad Code Example

    for (Account acc: accounts) {
    List<Contact> contacts = [SELECT Id, Name FROM Contact WHERE AccountId = :acc.Id];
    }

    Best Practice (Fix)

    Use bulkified queries outside the loop. We can get all account IDs and then execute a single SOQL to get all records with those account IDs. This will reduce the performance overhead.

    Set<Id> accountIds=new Set<Id>();
    for (Account acc: accounts) {
    accountIds.add(acc.Id);
    }
    Map<Id, Contact> contactMap= new Map<Id, Contact>([SELECT Id,Name FROM Contact WHERE AccountId IN :accountIds]);

    Refer to our post Optimizing Loop in Apex Code for handling loops in apex code.

    2. Avoid DML Statements Inside Loops

    Salesforce allows a maximum of 150 DML statements per transaction. Performing INSERT, UPDATE, DELETE, or UPSERT inside a loop can lead to governor-limit exceptions.

    Bad Code Example

    for (Opportunity opp: oppList) {
    opp.Status='Closed';
    update opp; // BAD PRACTICE
    }

    Best Practice (Fix)

    Use bulk processing and perform DML operations outside the loop.

    for (Opportunity opp: oppList) {
    opp.Status='Closed';
    }
    update oppList; // GOOD PRACTICE

    Check out our post Optimizing Salesforce Apex Code for handling DML inside the loop.

    3. Avoid Hardcoded IDs

    Hardcoding record IDs makes the code non-reusable and breaks deployments between different environments (Sandbox, UAT, Production).

    Bad Code Example

    List<Case> accs = [SELECT Id FROM Case WHERE RecordTypeId= '012300000012BYNQAG']; // BAD PRACTICE

    Best Practice (Fix)

    Use custom metadata, custom settings, or dynamic queries to retrieve records dynamically.

    CaseRecordTypeSetting__c recType = CaseRecordTypeSetting__c.getInstance();
    List<Case> accs = [SELECT Id FROM Case WHERE RecordTypeId= :recType.CaseRecordType__c];

    Check out our post Best Practices to Avoid Hardcoding in Apex for Cleaner Salesforce Code for best practices to avoid hardcoding in Apex.

    4. Use Proper Exception Handling

    Apex code without exception handling can result in uncaught exceptions, causing transaction failures or unwanted system exceptions. This can lead to poor user experience.

    Bad Code Example

    public void updateCase(Id recId) {
    Case casRec = [SELECT Id,Email__c FROM Case where Id=:recId];
    casRec.Email__c = 'test@example.com';
    update casRec; // NO ERROR HANDLING
    }

    Best Practice (Fix)

    Wrap the code inside a try-catch block to handle exceptions gracefully.

    public void updateCase(Id recId) {
    try {
    Case casRec = [SELECT Id,Email__c FROM Case where Id=:recId];
    casRec.Email__c = 'test@example.com';
    update casRec;
    } catch (DmlException e) {
    System.debug('Error updating case: ' + e.getMessage()); // GOOD PRACTICE
    }
    }

    Check out our post Exception Logging in Custom Object : Salesforce Apex for handling exceptions.

    5. Use with Sharing for Security

    Classes without with sharing keyword can access all records, potentially violating data security rules.

    Bad Code Example

    public class AccountHandler {
    public List<Account> getAllAccounts() {
    return [SELECT Id, Name FROM Account]; // EXPOSES ALL RECORDS
    }
    }

    Best Practice (Fix)

    Use with sharing to enforce user permissions. In this code, the user will only get records to which he/she has access.

    public with sharing class AccountHandler {
    public List<Account> getAllAccounts() {
    return [SELECT Id, Name FROM Account with USER_MODE]; // GOOD PRACTICE
    }
    }

    Check out our post Secure Apex Code with User Mode Operation for handling user mode operations.

    6. Avoid Unused Variables and Methods

    Unused variables and methods increase code complexity and affect readability. This will also increase the code line in Salesforce org.

    Bad Code Example

    public class TaxCalculationService {
    private String recId; // UNUSED VARIABLE
    public void calculateTestTax() {


    } // UNUSED METHOD
    }

    Best Practice (Fix)

    Remove unnecessary code to improve maintainability. It will also increase code lines that can be utilized for other features.

    public with sharing class TaxCalculationService {
    }

    Check out the post How to Manage Technical Debt in Salesforce to handle unwanted Code.

    7. Avoid System.debug() in Production Code

    Excessive System.debug() statements in production can cause log bloat and performance issues.

    Bad Code Example

    System.debug([select id from Account]); // SHOULD NOT BE IN PRODUCTION

    Best Practice (Fix)

    Use debug logs only for testing and remove them before deployment.

    if (System.isDebug()) {
    System.debug('This is for debugging only'); // GOOD PRACTICE
    }

    Check out the post Optimize Code by Disabling Debug Mode for handling debug mode.

    8. Use Constants Instead of Hardcoded Values

    Hardcoded values reduce code flexibility and maintainability.

    Bad Code

    public class DiscountCalculator {
    public Double calculateDiscount(Double price) {
    return price * 0.10; // HARDCODED VALUE
    }
    }

    Best Practice (Fix)

    Use constants for better maintainability. This way we can easily change value in the future and it will reflect in all places.

    public class DiscountCalculator {
    private static final Double DISCOUNT_RATE = 0.10;

    public Double calculateDiscount(Double price) {
    return price * DISCOUNT_RATE; // GOOD PRACTICE
    }
    }

    Check out the post How to Manage Technical Debt in Salesforce to handle this issue.

    9. Use Proper Variable Naming Conventions

    Poorly named variables make code hard to read and understand. The Developer will forget use of this variable.

    Bad Code

    String a = 'John Doe'; // UNCLEAR VARIABLE NAME

    Best Practice (Fix)

    Use meaningful variable names for better readability. This will enhance developer productivity.

    String customerName = 'John Doe'; // GOOD PRACTICE

    Check out the post How to Manage Technical Debt in Salesforce to handle this issue.

    10. Validate CRUD before DML Operation

    CRUD operations can lead to unwanted DML operations. We should avoid DML operation if the user does not have access to record/object.

    Account[] accts = [SELECT Id, Name FROM Account WHERE Name = 'Universal Containers' ALL ROWS]; 
    delete accts;

    We can utilize object and field permission before performing DML Operations. This will stop the DML operation if the er doesnot

    Account[] accts = [SELECT Id, Name FROM Account WHERE Name = 'Universal Containers' ALL ROWS];
    if (Schema.sObjectType.Account.isDeletable()) {
    delete accts;
    }

    Check out the post Enforce Object-level and Field-level permissions in Apex to handle this issue.

    Summary

    PMD is an excellent tool for identifying critical code quality issues. It helps Salesforce Developers write secure, efficient, and more maintainable code. Ideally, Developers should run a PMD scan after every change in the Salesforce Apex code. Regularly running PMD scans on Apex code will prevent governor limit violations, security risks, and performance issues.

    Related Posts

    • How to Manage Technical Debt in Salesforce
    • Optimizing Salesforce Apex Code
    • DML or SOQL Inside Loops
    • Limiting data rows for lists
    • Disabling Debug Mode for production
    • Stop Describing every time and use Caching of the described object
    • Use Filter in SOQL
    • Avoid Heap Size
    • Optimize Trigger
    • Bulkify Code
    • Foreign Key Relationship in SOQL
    • Defer Sharing Rules
    • Avoid Hardcode in code
    • Use Platform Caching

    apex code analysis code analyzer code bulkification code coverage in Salesforce code debt code management code optimization code optimization in salesforce code quality code review points code review tools Code Scanning. codescan pmd salesforce Salesforce PMD
    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
    Previous ArticleHow to Use Graph API for Outlook-Salesforce Connection
    Next Article How to Suppress PMD Warnings in Salesforce Apex
    Dhanik Lal Sahni
    • Website
    • Facebook
    • X (Twitter)

    With over 18 years of experience in web-based application development, I specialize in Salesforce technology and its ecosystem. My journey has equipped me with expertise in a diverse range of technologies including .NET, .NET Core, MS Dynamics CRM, Azure, Oracle, and SQL Server. I am dedicated to staying at the forefront of technological advancements and continuously researching new developments in the Salesforce realm. My focus remains on leveraging technology to create innovative solutions that drive business success.

    Related Posts

    By Dhanik Lal Sahni6 Mins Read

    Unlock the Power of Vibe Coding in Salesforce

    April 30, 2025
    By Dhanik Lal Sahni5 Mins Read

    How to Implement Dynamic Queueable Chaining in Salesforce Apex

    April 21, 2025
    By Dhanik Lal Sahni5 Mins Read

    How to Implement Basic Queueable Chaining in Salesforce Apex

    March 31, 2025
    Add A Comment
    Leave A Reply Cancel Reply

    Ranked #1 SALESFORCE DEVELOPER BLOG BY SALESFORCEBEN.COM
    Featured on Top Salesforce Developer Blog By ApexHours
    Recent Posts
    • Unlock the Power of Vibe Coding in Salesforce
    • How to Implement Dynamic Queueable Chaining in Salesforce Apex
    • How to Implement Basic Queueable Chaining in Salesforce Apex
    • How to Suppress PMD Warnings in Salesforce Apex
    • Top 10 PMD Issues Salesforce Developers Should Focus on in Apex
    Ranked in Top Salesforce Blog by feedspot.com
    RSS Recent Stories
    • How to Connect Excel to Salesforce to Manage Your Data and Metadata February 9, 2025
    • Difference Between With Security and Without Security in Apex January 2, 2025
    • Top Reasons to Love Salesforce Trailhead: A Comprehensive Guide December 5, 2024
    • How to Utilize Apex Properties in Salesforce November 3, 2024
    • How to Choose Between SOQL and SOSL Queries July 31, 2024
    Archives
    Categories
    Tags
    apex (110) apex code best practice (8) apex rest (11) apex trigger best practices (4) architecture (22) Asynchronous apex (9) AWS (5) batch apex (9) batch processing (4) code optimization (8) custom metadata types (5) design principle (9) file upload (3) flow (14) future method (4) google (6) google api (4) integration (19) integration architecture (6) lighting (8) lightning (64) lightning-combobox (5) lightning-datatable (10) lightning component (29) Lightning web component (61) lwc (50) named credential (8) news (4) optimize apex code (4) Permission set (4) Queueable (9) rest api (23) S3 Server (4) salesforce (139) salesforce apex (46) salesforce api (4) salesforce api integration (5) Salesforce GraphQL API (3) Salesforce Interview Question (4) salesforce news (5) salesforce question (5) shopify api (3) solid (6) tooling api (5) Winter 20 (8)

    Get our newsletter

    Want the latest from our blog straight to your inbox? Chucks us your detail and get mail when new post is published.
    * indicates required

    Ranked #1 SALESFORCE DEVELOPER BLOG BY SALESFORCEBEN.COM
    Featured on Top Salesforce Developer Blog By ApexHours
    Recent Posts
    • Unlock the Power of Vibe Coding in Salesforce
    • How to Implement Dynamic Queueable Chaining in Salesforce Apex
    • How to Implement Basic Queueable Chaining in Salesforce Apex
    • How to Suppress PMD Warnings in Salesforce Apex
    • Top 10 PMD Issues Salesforce Developers Should Focus on in Apex
    Ranked in Top Salesforce Blog by feedspot.com
    RSS Recent Stories
    • How to Connect Excel to Salesforce to Manage Your Data and Metadata February 9, 2025
    • Difference Between With Security and Without Security in Apex January 2, 2025
    • Top Reasons to Love Salesforce Trailhead: A Comprehensive Guide December 5, 2024
    • How to Utilize Apex Properties in Salesforce November 3, 2024
    • How to Choose Between SOQL and SOSL Queries July 31, 2024
    Archives
    Categories
    Tags
    apex (110) apex code best practice (8) apex rest (11) apex trigger best practices (4) architecture (22) Asynchronous apex (9) AWS (5) batch apex (9) batch processing (4) code optimization (8) custom metadata types (5) design principle (9) file upload (3) flow (14) future method (4) google (6) google api (4) integration (19) integration architecture (6) lighting (8) lightning (64) lightning-combobox (5) lightning-datatable (10) lightning component (29) Lightning web component (61) lwc (50) named credential (8) news (4) optimize apex code (4) Permission set (4) Queueable (9) rest api (23) S3 Server (4) salesforce (139) salesforce apex (46) salesforce api (4) salesforce api integration (5) Salesforce GraphQL API (3) Salesforce Interview Question (4) salesforce news (5) salesforce question (5) shopify api (3) solid (6) tooling api (5) Winter 20 (8)

    Get our newsletter

    Want the latest from our blog straight to your inbox? Chucks us your detail and get mail when new post is published.
    * indicates required

    Facebook X (Twitter) Instagram Pinterest YouTube Tumblr LinkedIn Reddit Telegram
    © 2025 SalesforceCodex.com. Designed by Vagmine Cloud Solution.

    Type above and press Enter to search. Press Esc to cancel.

    Ad Blocker Enabled!
    Ad Blocker Enabled!
    Our website is made possible by displaying online advertisements to our visitors. Please support us by disabling your Ad Blocker.