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
Waqar Hussain SFWaqar Hussain SF 

How to populate self lookup field using external Id in one dml statement


Hi all,

I have a custom object Task__c on which there is a self lookup field named dependent task (lookup to itself Task__c). I also have an external Id field on task object. Now I am inserting task records using  external Id in one statement. But I am getting this error

INVALID_FIELD, Foreign key external ID: task1 not found for field Dependent_Task__c in entity Task__c

See the code below.
 
List<sObject> TaskList = new List<sObject>();

Task__c objOne = new Task__c();
objOne.Name = 'Task1';
objOne.ExternalId__c = 'Task1';
TaskList.add(objOne);

Task__c objTwo = new Task__c();
objTwo.Name = 'Task2';
Task__c tempTask = new Task__c(ExternalId__c = 'Task1');
objTwo.Dependent_Task__r = tempTask;
TaskList.add(objTwo);

Database.SaveResult[] results = Database.insert(TaskList);

I guess the issue can be with sort order, because I was getting task2,task1 in list. So I tried sort method to sort the records in ascending order, but no luck
 
TaskList.sort();
Database.SaveResult[] results = Database.insert(TaskList);


Any Idea how this can be accomplish. How we can populate itself lookup using external Id in one dml statement. Any help will be appricated.
Thanks for your tme.
Best Answer chosen by Waqar Hussain SF
Alain CabonAlain Cabon
Hi,

That is not possible in a single DML statement with the same sObject. I fully reproduced your problem and the reason is written here:

"You can create related records that are up to 10 levels deep. Also, the related records created in a single call must have different sObject types. "

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

Your syntax is fully correct using the sample for opportunity and account ( tempTask and so one) but that is impossible with the same sObject.

So the parent object ( objOne  ) must be inserted first in a first DML statement.

Regards

All Answers

NagendraNagendra (Salesforce Developers) 
Hi Waqar,

Take a look at Creating Parent and Child Records in a Single Statement Using Foreign Keys(https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_foreign_keys.htm) Hope this helps.

Please mark this as solved if it's resolved.

Thanks,
Nagendra
Waqar Hussain SFWaqar Hussain SF
Following below article, I am unable to insert the list 

https://developer.salesforce.com/docs/atlas.en-us.206.0.api.meta/api/sforce_api_calls_create.htm#MixedSaveSection


See the code below
 
List<sObject> TaskList = new List<sObject>();

Task__c objOne = new Task__c();
objOne.Name = 'Task1';
objOne.ExternalId__c = 'Task1';
TaskList.add(objOne);

Task__c objTwo = new Task__c();
objTwo.Name = 'Task2';
Task__c tempTask = new Task__c(ExternalId__c = 'Task1');
objTwo.Dependent_Task__r = tempTask;
TaskList.add(objTwo);

Database.SaveResult[] results = Database.create(TaskList);

 
Alain CabonAlain Cabon
Hi,

That is not possible in a single DML statement with the same sObject. I fully reproduced your problem and the reason is written here:

"You can create related records that are up to 10 levels deep. Also, the related records created in a single call must have different sObject types. "

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

Your syntax is fully correct using the sample for opportunity and account ( tempTask and so one) but that is impossible with the same sObject.

So the parent object ( objOne  ) must be inserted first in a first DML statement.

Regards
This was selected as the best answer
Waqar Hussain SFWaqar Hussain SF
Yeah, I have now understood the problem. But I am creating a bunch of parent and child records using external Id where a child recod record have lookup to itself. 

I have now solve the issue by developing a trigger on task object on after insert. In this trigger I am populating lookup field based on some conditions. 

So I think workaround is to only write an after insert trigger and then update the tasks with populating lookup field. 

Thanks for your cooperation and time.
Alain CabonAlain Cabon
Thanks Waqar Hussain. This forum serves me as a study/training field to improve my knowledge of Salesforce and I'm learning a lot in the process of searching the reason of an intriguing question like this one (I replicated your code and that should work according the sample of SF but that don't).
Waqar Hussain SFWaqar Hussain SF
Yeah Alain, That should work but I think due circle dependency salesforce does not allow to insert same sObject types in a single dml call.