[SalesForce] sObject.addError did not prevent dml operation

I currently have trigger that executes on before insert. I was able to add an error message through the method addError() and was able to display it properly in my visualforce page. As I have read, this should have prevented the insertion of the objects in Trigger.new. But still, the objects are being inserted. How do i prevent the objects from being inserted when an error is added in sObjects?

The purpose of my trigger is to check whether there were records with duplicate name and number. When a user tries to insert new record with the same name and number with an existing record, the page would properly display the error message and would not insert the new record. But when multiple users try to add new records at the same time, this problem occurs. At first it would display that salesforce is not able to get an exclusive access(because another user is trying to access it) but when the user retries to insert new record, new records will be inserted even though there was an error message displayed(the one I have added through addError method).

As an additional information, the trigger.new contains a list of sObjects.

Here is my code for the Trigger:

trigger Testing_Trigger on Sample__c (before insert) {
List<Sample__c> newRecList = Trigger.new;
List<Sample__c> recList;
Set<String> recListNames = new Set<String>();
Map<String, sampleObj> recMap = new Map<String, sampleObj>();

For(Sample__c rec : newRecList){
    recListNames.add(rec.Name);
}

recList = [Select Name, Rec_No__c from Sample__c where Name IN: recListNames];

For(Sample__c rec : recList){
    sampleObj sObj = recMap.get(rec.Name);
    if(sObj != null){
        sObj.sRecList.add(rec);
    }else{
        sObj = new sampleObj();
        sObj.sRecList = new List<Sample__c>{rec};
    }
    recMap.put(rec.Name, sObj);
}

For(Sample__c rec : newRecList){
    sampleObj sObj = recMap.get(rec.Name);
    if(sObj == null){
        continue;
    }
    For(Sample__c sRec : sObj.sRecList){
        If(sRec.Rec_No__c == rec.Rec_No__c){
            rec.addError('Record with the same Name and record number already exists.');
            continue;
        }
    }
}

public class sampleObj{
    public List<Sample__c> sRecList{get;set;}
}
}

Best Answer

First of all, the duplicate checking can be done in a couple of ways:

  1. Use the trigger recipe like this one
  2. Use SFDC OOB Duplicate Management - introduced in Spring(?) 15

As @ajay noted, addError() needs to be used against Trigger.new (or any variable that is a reference to Trigger.new)

Duplicate checking involves checking intrabatch (are there any duplicates within Trigger.new) as well as extraBatch (are there any duplicates when considering records already saved by previous transactions)

You also need to check for duplicates on before insert and before update unless the key fields become read-only after insertion

Related Topic