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
Ian SidleIan Sidle 

How to clone Parent-Child records, stored in a List<Sobject> using External Id?

This is a very specific request, so I will try to include  simplified code/data structure to demonstrate. 
 
I am trying to clone records with parent-child lookup fields and use an external id so they can be inserted into the database simultaneously (vs having to insert parent first and then populate id into child).  

Data Model
ObjectA__c
External Id Field ExtId__c
 
ObjectB__c
Lookup Field to ObjectA called LookupA__c
 
Code 
//Make example records the regular way
ObjectA__c ExampleA=new ObjectA__c();
insert ExampleA;
system.debug(ExampleA); //Output = ObjectA__c:{Id=a6A540000000A4uEAE}

ObjectB__c ExampleB=new ObjectB__c();
ExampleB.LookupA__c=ExampleA.id;
insert ExampleB;
system.debug(ExampleB); //Output = {LookupA__c=a6A540000000A4uEAE, Id=a6B540000004SCaEAM}
 
//So far, so good….
 
//Try clone and use foreign key insert
List<Sobject> ToInsert = new List<SObject>();
 
ObjectA__c NewA = ExampleA.clone(false,true,false,false);
NewA.ExtId__c='NewA';
system.debug(NewA); //Output = ObjectA__c:{Extid=NewA}
ToInsert.add(NewA);
 
ObjectB__c NewB= ExampleB.clone(false,true,false,false);
System.debug(NewB) //Output = {LookupA__c=a6A540000000A4uEAE}
NewB.LookupA__c=null; //Trying to make this empty
NewB.LookupA__r=null; //Really Trying to make this empty
System.debug(NewB) //{LookupA__c=null} //Looks empty to me

NewB.LookupA__r=new ObjectA__c(Extid__c='NewA');
System.debug(NewB) //{LookupA__c=null} //Still Looks empty
ToInsert.add(NewB);

insert ToInsert; //FATAL_ERROR System.DmlException: Insert failed. First exception on row 1; first error: INVALID_FIELD, Cannot specify both an external ID reference LookupA__r and a salesforce id, LookupA__c: []
 
Questions
How do  I un-specify the lookupA__c?
It is pre-populated by the clone operation and setting it to null doesn't seem to count. 
Am I missing a step somewhere?
Is there a undocumented way to tell clone to exclude the LookupA__c field or something?
 
I am trying to avoid making my own clone method (getdescribe and copy values) or use multipule DML operations.
 
karthikeyan perumalkarthikeyan perumal
Hello 

use something like below.
 
ObjectA__c NewA = ExampleA.clone(false,true,false,false);
NewA.ExtId__c='NewA_clone';
ObjectB__c NewB= ExampleB.clone(false,true,false,false);
NewB.LookupA__r=new ObjectA__c(ExtId__c = NewA.ExtId__c);;

upsert ObjectA__c ;
upsert ObjectB__c ;
Hope this will help you. 

Thanks
karthik

 
Ian SidleIan Sidle
Hi karthik,

Thank you for responding but this uses upsert twice which results in two DML operations (which is what I want to avoid)

-Ian