0 votes
1 view
by

I have written the following class for preventing an Account with the same name to get created in the org. The issue with the trigger is that it is not allowing the record to be saved but the error message to be shown is not as intended.

Apex Trigger:

    trigger AccountTrigger on Account (before insert, before delete) {
        if(Trigger.isBefore){
            if(Trigger.isInsert){
                DuplicateAccount.DuplicateAccountHandler(Trigger.new);
        }
            
    }
}

Apex Class:

public with sharing class DuplicateAccount {
   public static void DuplicateAccountHandler(List<Account> listAccount){
        Set<String> accountName = new Set<String>();
        for(Account accVar : listAccount){
            accountName.add(accVar.Name);
        }
        List<Account> duplicateAccounts = [SELECT Id, Name 
                                             FROM Account 
                                             WHERE Name IN :accountName]; 
        
        for(Account acc : duplicateAccounts){
            if(duplicateAccounts.size()!=0){
                acc.Name.addError('Account cannot be inserted');
            }
        }
    }
}

Error Message

1 Answer

0 votes
by
 
Best answer

To add an error to record in a trigger, you must use the records in Trigger.new/Trigger.newMap/Trigger.old/Trigger.oldMap. You're looping over the wrong variable to use for the error.

public with sharing class DuplicateAccount {
   public static void DuplicateAccountHandler(List<Account> listAccount){
        Set<String> accountName = new Set<String>();
        for(Account accVar : listAccount){
            accountName.add(accVar.Name);
        }
        List<Account> duplicateAccounts = [SELECT Id, Name 
                                             FROM Account 
                                             WHERE Name IN :accountName]; 
        
        for(Account acc : listAccount){ // Use Trigger.new records
            if(duplicateAccounts.size()!=0){
                acc.Name.addError('Account cannot be inserted');
            }
        }
    }
}

However, please note that this code will prevent any accounts from being created, as you're also querying the records that were literally just created.

Duplicate Management is relatively difficult to get correct writing your code, so it's strongly suggested you use Duplicate Management instead of writing your code.

There are ways to do this correctly, but you've not thought through all the possible things that could go wrong. If you insist on doing code anyways, you should search here on SFSE for examples that include the proper way to block duplicates in code.

A proper trigger to prevent duplicate must use row locking (FOR UPDATE) to catch all records that may be being updated in other transactions, must check for duplicates in the current batch of this trigger context, must be bulk-safe by checking for each name individually, and must make sure that it doesn't include the records in the current transaction.

Welcome to Memory Exceeded, where you can ask questions and receive answers from other members of the community.
...