function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Pavan Kumar 1072Pavan Kumar 1072 

INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call:

I have a requirement to share lead records to a particular user when team = Bangalore team.

And team field is updating based on the owner of the lead record. Now I'm trying to create a test class for this requirement. But I'm facing an issue.

System.DmlException: Upsert failed. First exception on row 0 with id 00QN0000008KXuhMAG; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, Trigger: execution of AfterUpdate

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

Class.LeadSharing.BangaloreTeamShareUpdateordelete: line 47, column 1

Apex Test Class:

 
Static testmethod void testUpdateLeads()
    {
        List<Lead> leads = new List<Lead>{};
        Id queueID=[Select Queue.Id,Queue.name from QueueSObject where Queue.Name = 'Charlotte Leads' LIMIT 1].Queue.ID;
        Id userid=[Select id,name from user where name='Pavan Kumar' Limit 1].Id;
        for(Integer i = 0; i < 20; i++) 
        {
            Lead a = new Lead(lastName='TestCavalry'+ i,RecordTypeId ='0126F0000016MZP',
                              Company ='Azuga Cavalry'+ i,Status='New',Account_Category_new__c='Prospect',
                              Account_Category__c='Regular',Lead_Category__c='Sales',Lead_Type__c='Association List',
                              Lead_Source__c='NEFBA',LGS_Owner_new__c='Cavalry Test',ownerid=queueID);
            leads.add(a);
        }
        test.startTest();
        // Insert the Account records that cause the trigger to execute.
        insert leads;
        // Stop the test, this changes limit context back to test from trigger.
        test.stopTest();
        // assert that 0 shares exist
        List<LeadShare> shares = [select id from LeadShare where 
                                     LeadId IN :Leads and RowCause = 'Manual'];
        System.assertEquals(shares.size(),0);
        for(Lead leadidss:leads)
        {
            leadidss.ownerid=userid;
        }
        update leads;
        // assert that 20 shares were created
        shares = [select id from LeadShare where LeadId IN :leads and RowCause = 'Manual'];
        System.assertEquals(shares.size(),20);
        /*
        **for(Lead leadids:leads)
        {
            leadids.ownerid=QueueID;
        }**
        update leads;
        // assert that 0 shares were created
        shares = [select id from LeadShare where LeadId IN :leads and RowCause = 'Manual'];
        System.assertEquals(shares.size(),0);*/
    }

And line 47 would be.
 
for(Lead leadids:leads)
            {
                leadids.ownerid=QueueID;
            }

Apex Class:
 
public static void BangaloreTeamShareUpdateordelete(List<Lead> newleads,Map<Id,Lead> oldmapleads)
    {
        List<Id> Sharedeletionlist = new List<Id>();
        List<LeadShare> Shareinsertlist = new List<LeadShare>();
        for(Lead leadid:newleads)
        {
            if(oldmapleads.get(leadid.id).team__c == 'Bangalore Team' && 
               (leadid.Team__c <> 'Bangalore Team' || String.isBlank(leadid.Team__c)) )
            {
                Sharedeletionlist.add(leadid.id);
            }
            else if((oldmapleads.get(leadid.Id).team__c <> 'Bangalore Team' || String.isBlank(oldmapleads.get(leadid.id).team__c)) && 
                    leadid.Team__c == 'Bangalore Team')
            {
                leadshare leadshareid= new leadshare();
                leadshareid.LeadId=LeadId.Id;
                leadshareid.UserOrGroupId=userid;
                leadshareid.LeadAccessLevel='edit';
                Shareinsertlist.add(leadshareid);
            }
            if(Sharedeletionlist <> null && !Sharedeletionlist.isEmpty())
            {
                delete[Select id from leadshare where leadid IN :Sharedeletionlist AND RowCause='Manual'];
            }
            If(Shareinsertlist <> null && !Shareinsertlist.isEmpty())
            {
                insert Shareinsertlist;
            }
        }
    }

I tried multiple ways like disabling parallel apex test execution. And updating update DML statement to upsert.

Please guide me where I went wrong.
 
Abdul KhatriAbdul Khatri
Please share your trigger context, I mean is your trigger firing before insert, Please remove that if it is but if you want your trigger fires even before insert that you need to make some changes in your classs as oldMap and Id fields are not available in that context.
 
trigger trggername on sobject (before insert, ...)

 
pavan kumar 177pavan kumar 177
trigger UpdateTerritories on Lead (Before insert,Before Update,After Insert,After Update) 
{
if(Trigger.isAfter && trigger.isUpdate) 
    {
            LeadSharing.BangaloreTeamShareUpdateordelete(trigger.new, trigger.oldmap);
    }
}
I'm doing after update operation.
Abdul KhatriAbdul Khatri
Please try this
 
trigger UpdateTerritories on Lead (Before Update,After Insert,After Update) 
{
if(Trigger.isAfter && trigger.isUpdate) 
    {
      LeadSharing.BangaloreTeamShareUpdateordelete(trigger.new, trigger.oldmap);
    }
}

 
pavan kumar 177pavan kumar 177
What's the difference on your code.I didn't understand will you please explain a bit briefly
Abdul KhatriAbdul Khatri
User-added image