+ Start a Discussion
Sarah SSarah S 

System.DmlException: Insert failed. First exception on row 0 with id 0010I00002TQaLoQAL; first error: INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call: [Id]

Hello
I am getting below error while running the test class.

System.DmlException: Insert failed. First exception on row 0 with id 0010I00002TQaLoQAL; first error: INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call: [Id]


My trigger is-
---------------------

trigger NewAccountTrigger on Account (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
    
    if(Trigger.isBefore){
        if(Trigger.isInsert){
        //call the handler method BEFORE INSERT
        NewAccountTriggerHandler.beforeInsert(Trigger.new);  
        }
        else if(Trigger.isUpdate){
              //call the handler method BEFORE UPDATE   
             NewAccountTriggerHandler.beforeUpdate(Trigger.new);  
            }
        else if(Trigger.isDelete){
                //call the handler method BEFORE DELETE
                NewAccountTriggerHandler.beforeDelete(trigger.old);
    }
        }
    if(Trigger.isAfter){
 }
}

My Trigger Handler Class-
--------------------------------------
public class NewAccountTriggerHandler {
    
    public static void beforeInsert(list<Account> accs){
      for (Account a : accs){
                a.Nick_Name__c = 'FromBeforeinsertHandlerClass';
            }       
    } 
    
    public static void beforeUpdate(list<Account> accs){
   //Do something here      
    } 
    
    public static void beforeDelete(list<Account> accs){
    //do something here
                }    
    } 

My test class is -
-------------------------
@isTest
private class NewTestAccountTriggerHandler {
    @isTest static void TestBeforeInsert() {
        // Test data setup
        list<account>accountlist = new list <account>();
        account acct1 = new account();
        acct1.name = 'Trigger test 1';
        accountlist.add (acct1);
        insert  accountlist ;
        
        // Perform test
        Test.startTest();
        
        Database.SaveResult[] result = Database.insert(accountlist, true);

        Test.stopTest();
        // Verify 
        System.assert(result[0].isSuccess());
        System.assertEquals(accountlist[0].Nick_Name__c, 'FromBeforeinsertHandlerClass');
        
    }
    
}
 
David Zhu 🔥David Zhu 🔥
You will have to remove line insert accountlist as you did database insert again in the code.
​​​
   acct1.name = 'Trigger test 1';
        accountlist.add (acct1);
        insert  accountlist ;
        
        // Perform test
        Test.startTest();
        
        Database.SaveResult[] result = Database.insert(accountlist, true);. //insert twice
Sarah SSarah S
Thanks David,
I removed the insert accountlist line, and not getting the said error. But still the record is not added in the database. That's why I am now getting error on assert operation. Can you suggest why the record is not inserted?
David Zhu 🔥David Zhu 🔥
You need to add the following line before assertion.

Accountlist = [select  Nick_Name__c from account];
Sarah SSarah S
Not working...the account record is not added in the first place. 
David Zhu 🔥David Zhu 🔥
Are there required fields missing when building account in your test class?

Try the code in anonymous window?

    list<account>accountlist = new list <account>();
        account acct1 = new account();
        acct1.name = 'Trigger test 1';
        accountlist.add (acct1);
        insert  accountlist ;
Andrew GAndrew G
the first error occurs because you do this code snippet:
insert  accountlist ;
        
        // Perform test
        Test.startTest();
        
        Database.SaveResult[] result = Database.insert(accountlist, true);

The first Insert will insert the test data and therefore assign an "in memory" Id to the record that is inserted.  So now the records in Account List have an ID and therefore when you do the call for the Database.Insert you are trying to insert the records with an Id.

Now, as noted, removing the first insert will alleviate that issue, because the database.insert will work as there is no preexisting Id on the test data.

Now, why doesn't the assert work.  Because we need to understand the concept of "in memory" and "on disc".  
In this post, near the bottom of the thread, I cover this concept in depth.
https://developer.salesforce.com/forums/ForumsMain?id=9062I000000IKZFQA4

But basically, the code to write the value to the Nick Name field occurs on Insert.  The record (where the nick name has been written) is now on disc, not in memory.  Therefore for your assert to work, you need to grab the record from the disc, not try and use the one "in memory".

 
// Perform test
        Test.startTest();
        
        Database.SaveResult[] result = Database.insert(accountlist, true);

        Test.stopTest();
        // Verify 

        List<Account> updatedAccounts = [SELECT Nick_Name__c FROM Account WHERE Id = :accountlist[0].Id];

        System.assertEquals(1,updatedAccounts.size());
        System.assertEquals('FromBeforeinsertHandlerClass',updatedAccounts[0].Nick_Name__c);
//note, asserts should be written System.assertEquals(ExpectedValue, ActualValue);


Regards
Andrew