Sometime back I came across a scenario where i wanted to insert both parent and child object records together.
There could be two ways to do it :
Refer to below link for more information.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_foreign_keys.htm
I have created code snippet to do same for custom objects, make sure you read through comments to learn about general errors that might come.
There could be two ways to do it :
- Insert parent record then insert child record using already insert parent record ID. Something similar to below.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Castle__c parent = new Castle__c ( name ='Castle'); | |
insert parent; | |
Personnel__c child = new Personnel__c (name='Personnel', castle__c = parent.Id); | |
insert child; | |
I noticed with this approach we will be using multiple DML statements and If I wanted to insert parent and child in bulk that would be whole another level of effort as I'd have to maintain relationship details.
- Another way would be to create a reference of parent record and use it to set foreign key reference on child record, once done insert both parent and child in single DML.
Refer to below link for more information.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_foreign_keys.htm
I have created code snippet to do same for custom objects, make sure you read through comments to learn about general errors that might come.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Castle is our parent object.Personnel is our child object. | |
List<Castle__c > lstCastle = new List<Castle__c>(); | |
List<Personnel__c> lstPersonnel = new List< Personnel__c >(); | |
Map<String,Castle__c> externalIdCastle = new Map<String,Castle__c>(); | |
List<SObject> combinedList = new List<SObject>(); | |
Castle__c parent; | |
Personnel__c child ; | |
for(Integer i =0 ; i<5; i++){ | |
parent = new Castle__c(name = 'parent'+String.valueOf(i),External_Id__c=String.valueOf(Integer.valueOf(Math.random()*10000))); | |
lstCastle.add(parent); | |
externalIdCastle.put(parent.name,parent); | |
} | |
// When passing reference in child we can only pass parent reference with External Id in it, we cant pass whole parent reference | |
// If we do code will exit with error as "More than 1 field provided in an external foreign key reference in entity" | |
// We have passed parent reference in child as castle__r (which is a relationship field), we cant use castle__c as it expects id and not reference. | |
for(Integer i=0; i<5; i++){ | |
Castle__c tempParent = new Castle__c (External_Id__c = externalIdCastle.get('parent'+String.valueOf(i)).External_Id__c); | |
child = new Personnel__c(name='child'+String.valueOf(i),Castle__r = tempParent); | |
lstPersonnel.add(child); | |
} | |
// Always add parent list before adding child list else it will throw error. | |
if(lstCastle.size()>0 && lstPersonnel.size()>0){ | |
combinedList.addAll(lstCastle); | |
combinedList.addAll(lstPersonnel); | |
} | |
// Single dml statement to insert both parent and child together. | |
Database.SaveResult[] results = Database.insert(combinedList); | |
// Iterating over results/ | |
for (Integer i = 0; i < results.size(); i++) { | |
if (results[i].isSuccess()) { | |
System.debug('Successfully created ID: '+ results[i].getId()); | |
} else { | |
System.debug('Error: could not create sobject '+ 'for array element ' + i + '.'); | |
System.debug(' The error reported was: '+ results[i].getErrors()[0].getMessage() + '\n'); | |
} | |
} |
Note above method will not work if you try to reference another record of same object type for example if you try to create both ParentAccount and Child Account in same transaction and try to link them using ParentId field, It will not work. In Self lookup scenarios you can only reference records which are already existing else divide them in different DML's
Thanks for reading...
If you liked the post do support me by buying a pizza for me :D
No comments:
Post a Comment