1

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

I get this error on a trigger i'm trying to run, I don't understand why it won't allow this create two similar records in an insert?

trigger ContractInvoices on ServiceContract (after update) {


    for (servicecontract sc: trigger.new)

    {
        invoice__c i = new invoice__c();
        Date yd = Date.today();
        Date ydd = yd.addmonths(1);

       if (sc.payment_type__c == 'yearly'){
           List  <invoice__C> invoiceYearly = new list <invoice__C>();
                   i.effective_date__c = yd;
                   i.vat__c = '13.5%';
                   i.Service_Contract__c = sc.id;
                   i.Invoice_date__c = yd;
                   i.Due_date__c = ydd;
                   i.Net_Value__c = sc.TotalPrice;
                   invoiceYearly.add(i);   
           insert invoiceYearly;
        }// end if yearly

        if (sc.Payment_Type__c == 'monthly'){

            List  <invoice__C> invoiceMonthly = new list <invoice__C>();
                       for(Integer intr=0; intr<12 ;intr++ )
           {

              Date md = Date.today().addMonths(intr);
              Date mdd = md.addmonths(1);

                   i.external_id__C = 'Invoice'+intr;
                   i.effective_date__c = md;
                   i.vat__c = '13.5%';
                   i.Service_Contract__c = sc.id;
                   i.Invoice_date__c = md;
                   i.Due_date__c = mdd;
                   i.Net_Value__c = sc.TotalPrice/12;
                   invoiceMonthly.add(i);  



           }//end for intr
            insert invoiceMonthly;
        }//end if monthly

    }//end for sc


}//end trigger

1 Answer 1

2

You are adding the same instance of i twelve times to the second list and the platform judges that to be a coding error - you will have twelve references to the data values set the last time round the loop not twelve different sets of data - and disallows it.

You need instead to create separate instances of invoice__c and add those to the list that is inserted:

trigger ContractInvoices on ServiceContract (after update) {

    List <invoice__C> inserts = new List <invoice__C>();

    for (servicecontract sc: trigger.new) {
        if (sc.payment_type__c == 'yearly'){
            Date yd = Date.today();
            Date ydd = yd.addmonths(1);

            invoice__c i = new invoice__c();
            i.effective_date__c = yd;
            i.vat__c = '13.5%';
            i.Service_Contract__c = sc.id;
            i.Invoice_date__c = yd;
            i.Due_date__c = ydd;
            i.Net_Value__c = sc.TotalPrice;
            inserts.add(i);

        }// end if yearly
        if (sc.Payment_Type__c == 'monthly'){
            for(Integer intr=0; intr<12 ;intr++ ) {
                Date md = Date.today().addMonths(intr);
                Date mdd = md.addmonths(1);

                invoice__c i = new invoice__c();
                i.external_id__C = 'Invoice'+intr;
                i.effective_date__c = md;
                i.vat__c = '13.5%';
                i.Service_Contract__c = sc.id;
                i.Invoice_date__c = md;
                i.Due_date__c = mdd;
                i.Net_Value__c = sc.TotalPrice/12;
                inserts.add(i);

            }//end for intr
        }//end if monthly
    }//end for sc

    insert inserts;

}//end trigger
2
  • Thanks that worked, but i'm not sure i fully understand the difference between the two Nov 20, 2014 at 21:12
  • @denisoleary This diagram may help. (Ignore the names it uses.) It represents the working version where there is a separate chunk of memory (created by new invoice__c()) for each list element. In the non-working version there was only one chunk of memory with all the list elements (0, 1, 2, 3 in the diagram) referencing it.
    – Keith C
    Nov 20, 2014 at 21:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .