[SalesForce] Inserting a child record with Parents external id not working

In one of our requirement we have to clone a parent and then also clone the child and attach the cloned child with the new cloned parent. The child and parent have a M-D relationship. There is two way to do it :

  1. Clone and Insert the parent first, then clone the child and assign appropriate cloned parent id on the child, and then insert the cloned child.

  2. Clone the parent, have some kind of External id that distinguishes original and cloned parent. Then clone the child, assign the Cloned parent using External id of it. Then insert both parent and child in order.

I am able to achieve the said functionality with Option 1, but to my surprise facing issues when trying to implement Option 2.
Below is sample code that I am trying to run :

ParentObj__c parentToClone = [Select id, name,External_Key__c from       
ParentObj__c where id='some id'];
ParentObj__c newParent = parentToClone.clone(false,true);
newParent.External_Key__c = newParent.External_Key__c + '_clone';
system.debug('newParent ++ = '+newParent);


ChildObj__c childToClone = [Select id, name,External_child_Key__c,
ParentObj__r.External_Key__c from ChildObj__c where id='some id'];
ChildObj__c newChild = childToClone.clone(false,true);
newChild.External_child_Key__c =   
childToClone.External_child_Key__c+'_clone';

newChild.ParentObj__r.External_Key__c = newParent.External_Key__c;

upsert newParent External_Key__c;
upsert newChild External_Child_Key__c;

For this code, it creates the parent record but attaches the new child with the old parent only. Which I think is due to the clone functionality also brings in the ParentObj__c id as well. But I am not sure why that external id for parent assignment is not working for child.
I have even tried putting the newChild ParentObj__c field as null and then try to do insert, but it throws an Required field missing error.

Any suggestions or thoughts to make Option 2 work?

Best Answer

For master details relations we need to pass the reference of object and we cant set the ParentObj__c field as null. Here is example from Apex documentation :

Opportunity newOpportunity = new Opportunity(
    Name='OpportunityWithAccountInsert',
    StageName='Prospecting',
    CloseDate=Date.today().addDays(7));

// Create the parent record reference.
// An account with this external ID value already exists.
// This sObject is used only for foreign key reference
// and doesn't contain any other fields.
Account accountReference = new Account(
    MyExtID__c='SAP111111');                

// Add the nested account sObject to the opportunity.
newOpportunity.Account = accountReference;

// Create the opportunity.
Database.SaveResult results = Database.insert(newOpportunity);

Your code should be something like this:

ParentObj__c parentToClone = [Select id, name,External_Key__c from       
ParentObj__c where id='some id'];
ParentObj__c newParent = parentToClone.clone(false,true);
newParent.External_Key__c = newParent.External_Key__c + '_clone';
system.debug('newParent ++ = '+newParent);

ChildObj__c childToClone = [Select id, name,External_child_Key__c,
ParentObj__r.External_Key__c from ChildObj__c where id='some id'];
ChildObj__c newChild = childToClone.clone(false,true);
newChild.External_child_Key__c =   
//childToClone.External_child_Key__c+'_clone';

newChild.ParentObj__c = newParent; // pass the reference of Parent where external id is already set.

upsert newParent External_Key__c;
upsert newChild External_Child_Key__c;

Ref: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_nested_object.htm

Related Topic