+ Start a Discussion
Sindhu NagabhushanSindhu Nagabhushan 

System.ListException: Before Insert or Upsert list must not have two identically equal elements

I have a competitor object. It has lookup and Master-detail relationship to Account Object. When i try to mass insert records, I get the follwing error
"autoinsertforcompetitor: execution of BeforeInsert caused by: System.ListException: Before Insert or Upsert list must not have two identically equal elements Trigger.autoinsertforcompetitor: line 48, column 1"

Here's my code

trigger autoinsertforcompetitor on Competing_Customer__c (before insert,after delete)
{
         list<Competing_Customer__c> newcompetitor=new list<Competing_Customer__c>();
     list<Competing_Customer__c> competitorlist=new list<Competing_Customer__c>();
     Competing_Customer__c competitor = new Competing_Customer__c();
   
    if (!TriggerHelperClass.hasAlreadyfired())
    {system.debug('in inset'+TriggerHelperClass.hasAlreadyfired());
        if(trigger.isInsert)
    {  
    for(Competing_Customer__c obj:trigger.new)
        {
          
        Competing_Customer__c[] comp=[select Account__c,Account_competitor__c from Competing_Customer__c where Account__c = :obj.account__c AND Account_competitor__c = :obj.Account_competitor__c];
      if (comp.size() > 0 )
      {
          system.Debug('in if');     
          obj.adderror('this is a duplicate entry');
      }
            else{
       system.debug('step');
                system.debug('in else');
           newcompetitor.add(obj);
            }
        }
   
    for(integer i=0;i<newcompetitor.size();i++)
        {

        competitor.Account__c=newcompetitor[i].Account_competitor__c;
        competitor.Account_competitor__c=newcompetitor[i].account__c;
        TriggerHelperClass.setAlreadyfired();
     
            competitorlist.add(competitor);
        }
  insert competitorlist;
       
    }
   
    }
    if(trigger.isDelete)
    {
        system.debug(TriggerHelperClass.hasAlreadyfired());
        if (!TriggerHelperClass.hasAlreadyfired())
            {
    for(Competing_Customer__c obj:trigger.old)
        {
            newcompetitor.add(obj);
        }
           
                try{
                for(integer i=0;i<newcompetitor.size();i++)
        {
        competitor=[select id from Competing_Customer__c where Account__c = :newcompetitor[i].Account_competitor__c AND Account_competitor__c = :newcompetitor[i].Account__c];
                competitorlist.add(competitor);
                TriggerHelperClass.setAlreadyfired();
            }
       
               
                delete competitorlist;}
                catch(exception e)
                {system.debug('catch error');}
    }
       
}
}
Darshan FarswanDarshan Farswan
Hi Sindhu,

I do not exactly know the flow of your code, but as per the Exception, when you insert or upsert the code in Database, then each record in the list must be unique. For a single record, no duplicate entries should be there.


So for your code :
Competing_Customer__c competitor = new Competing_Customer__c();
It should be defined inside the loop, where you are using competitor variable. It will add unique records to the competitorlist list.

Also you have not been following the best practices. SOQL inside for loop is not a good practice. Please get it ouside the loop using MAPS or LISTS.
Sindhu NagabhushanSindhu Nagabhushan
Hi Darshan,

Thank you very much.
I am new to apex coding.  Can you please help me how to use maps in my code.

The scenario here is,
When i insert a record to my competing customer object, A vice-versa of the record should get inserted.

Ex: IF i am inserting record --
Account - Account1
Account competitor - Account2

Then another record should get inserted in the following way --
Account - Account2 , account competitor - Account1
Darshan FarswanDarshan Farswan
Hi Sindhu

I might not write the whole code for you, it will not be good for you knowledge as well. But I can suggest you of the changes, that needs to be done. Lets consider the SOQL issue. Instead of following,

for (Competing_Customer__c obj: trigger.new) {
Competing_Customer__c[] comp = [select Account__c, Account_competitor__c from Competing_Customer__c where Account__c = : obj.account__c AND Account_competitor__c = : obj.Account_competitor__c];
}

try the following :

List<Id> accountIds = new List<Id>();
List<Id> competitorIds = new List<Id>();
for (Competing_Customer__c obj: trigger.new) {
accountIds.add(obj.Account__c);
competitorIds.add(obj.Account_competitor__c);
}
Competing_Customer__c[] comp = [select Account__c, Account_competitor__c from Competing_Customer__c where Account__c in :accountIds AND Account_competitor__c in :competitorIds];

This way, we do not get into SOQL 101 limit and help us Bulkify the code.

Just go through Salesforce Guides to get better idea of the same. Things are clearly explained over there.
For Best practices, refer to the link : https://developer.salesforce.com/page/Apex_Code_Best_Practices