2

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

But I'm trying to create a Parent and child records from the same sObject type on same Statement - is this possible ?

That's my code that fails:

MyCustomObject__c[] recordsToInsert = new List<MyCustomObject__c>();

// parent reference
MyCustomObject__c parentRef = new MyCustomObject__c();
     parentRef.put('ExternalId__c',’2’);

// record to create
MyCustomObject__c child = new MyCustomObject__c();
       child.put('Name','Test');
       child.put('ExternalId__c','1');
       child.put('ParentId__c', parentRef );


MyCustomObject__c parent = new MyCustomObject__c();
    parent.put('ExternalId__c','2');
    parent.put('Name','ParentTest');

recordsToInsert.add(parent);
recordsToInsert.add(child);

Database.SaveResult[] srList = Database.insert(recordsToInsert,true);

I get the following error :

Illegal assignment from ParentId__c to Id

What am I missing here in order to be able to upsert the ParentId__c lookup record based on external key ?

1

1 Answer 1

8

The original error, "Illegal assignment from ParentId__c to Id", is because you can't put an sObject into a field, but you could put it in to a relationship via putSObject:

   child.putsObject('ParentId__r', parentRef );

Note the use of the __r notation. The ID is always __c, the sObject it points to is __r. For standard relationships, you drop the Id. For example, Contact.AccountId is the Id field, Contact.Account is the relationship to an Account. However, the next error you'd get would have been:

Foreign key external ID: XXXXX not found for field ExternalId__c in entity MyCustomObject__c:

You need to insert the records one at a time, or relate them later. There is no "workaround" for this problem other than to use two DML statements. If this was a parent-detail situation (e.g. Account and Contact), then it would work correctly.

3
  • Thanks.. I have also tried to use '__r' notation or with '__r.External__Id__c' like you would do when upserting records using dataloader. each of those trials gave me a different error like the one you mentioned or 'Insert failed. First exception on row 1; first error: INVALID_FIELD, Foreign key external ID: 2 not found for field ExternalId__c in entity MyCustomObject__c: []
    – sfdx bomb
    Aug 19, 2019 at 10:11
  • I guess it does means I must use 2 DML statements => which makes it really hard when dealing with a Same sObjectType Tree structure Large data set to be used in Batch ... basically what I'm trying to do is to upsert the entire Tree as a flat list structure with external keys - but if any other suggestions exists will help a ton. Thanks !
    – sfdx bomb
    Aug 19, 2019 at 10:11
  • @sfdxbomb You could upsert all records without the "parent ref" in one pass, then upsert again with the "parent ref" field in on a second pass. This is probably how I'd do it, if possible. There's really no way to get around the two DML statement minimum no matter what you do at this point. There's simply no support for doing it all in one pass without making an API call.
    – sfdcfox
    Aug 19, 2019 at 11:56

You must log in to answer this question.

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