1

I often encounter usecases where i need to insert nested objects.

While i know that it is feasible to leverage external Ids to achieve the insert in a single DML operation

Account a = new Account(Name='Phil Household', theExternalId__c = 'externalValue');
Contact c = new Contact (FirstName = 'Phil', LastName = 'Uyt');
c.Account = new Account(theExternalId__c = 'externalValue');
toInsert.add(a);
toInsert.add(c);
insert toInsert;

I see that using the REST api composite tree, i am able to perform similar operation EXCEPT that i don't need to create external ID fields across the objects to be able to nest them in a single operation.

Indeed, documentation states that with this composit tree request :

The request can contain the following:

  • Up to a total of 200 records across all trees
  • Up to five records of different types
  • sObject trees up to five levels deep

Does anyone know if there is an exivalent to that action in APEX that would greatly simplify my (our?) lives?

refs :

Sobject tree : https://developer.salesforce.com/docs/atlas.en-us.234.0.api_rest.meta/api_rest/resources_composite_sobject_tree.htm

Nested insert : https://developer.salesforce.com/docs/atlas.en-us.234.0.api_rest.meta/api_rest/dome_composite_sobject_tree_create.htm

2 Answers 2

2

I would adopt the Unit Of Work pattern provided in Lightning Enterprise Architecture aka fflib aka apex-common

Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems

The Unit of Work pattern relieves the Apex code from managing maps of previously inserted records in order to provide the lookup (or master) Id for the child records.

Coupled with mocking frameworks like ApexMocks, The Unit of Work pattern enables faster Unit Testing without having to actually commit records to the database.

Buy the book (3rd edition), it is revelatory and easy to follow (I didn't write it but my Apex coding was profoundly affected by this work and underlying framework code).

0

You might want to look into this in case the Account already exists: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_nested_object.htm

If you want to create them both in one statement check this out: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_foreign_keys.htm

With your sample code snippet, something like this should work:

Account accountReference = new Account (theExternalId__c = 'externalValue');
Account accountParent = new Account(Name='Phil Household', theExternalId__c = 'externalValue');
Contact contactNew = new Contact (FirstName = 'Phil', LastName = 'Uyt');
contactNew.Account = aReference;

Database.SaveResult[] results = Database.insert(new SObject[] {aParent, contactNew });
2
  • Well the point is that i don't want to have external Ids field. In the REST API SObjec Tree, i just place a structured JSON, and salesforce is capable of linking the objects together uptil 5 level deep. That is what i want without having to have the external ids. To be more explicit : assume i have a task (t) for a case (ca) linked to a contact (c) linked to an account (a) all 4 to be created. With the sObject tree API, i just send the information structured in JSON and all 4 get created and linked together 1 transaction. No need for External Id fields on Case, Contact and Account.
    – Philippe
    Commented Nov 22, 2022 at 11:51
  • With Apex you basically would have 3 options: 1 -> via external ID (see links above) 2 -> manage it yourself (will require some coding) & possible queriieng data 3 -> Maybe via a callout to the REST API - which i would not recommend here
    – Muffinzlol
    Commented Nov 22, 2022 at 15:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .