0

I'm currently wrapping my head around inserting both parent records and child records at the same time. The second requirement is that all fields must be cloned.

Example: Clone an Account and all its Contacts.

In order to perform DML and match parent with child records I went for the External ID pattern which is referenced both in the Salesforce documentation and in several places on this platform.

In order to clone all fields from the initial record I want to use the SObject Class method Clone. A Select All fields query at the beginning of the script will query all fields (not included in my snippet). All good up to this point.

I tested the External ID pattern for this use case without the clone method and assigned the fields for the Contacts one by one - works like a charm.

The issue starts when the clone method comes into play on child level. The following code does not work - pay attention to myContact.clone(false, false, false, false).

List<Account> newAccountsToInsert = new List<Account>();
List<Contact> newContactsToInsert = new List<Contact>();

    for (Account myAccount : myAccounts) {

                Account myNewAccount = myAccount.clone(false, false, false, false);
                myNewAccount.External_ID_Test__c = String.ValueOf(Integer.valueOf(math.rint(math.random()*10000000)));
                newAccountsToInsert.add(myNewAccount);

                for (Contact myContact : accsWithContacts.get(myAccount.Id)) {

                     Contact myNewContact = myContact.clone(false, false, false, false);

                     Account virtualParentAccount             = new Account();
                     virtualParentAccount.External_ID_Test__c = myNewAccount.External_ID_Test__c;

                     myNewContact.Account = virtualParentAccount;

                     newContactsToInsert.add(myNewContact);

                }

            }                  
            insert newAccountsToInsert;
            insert newContactsToInsert;
        }

Upon executing the logic I'm receiving the following error message:

INVALID_FIELD, Cannot specify both an external ID reference Account and a salesforce id, AccountId

It's about the new Contacts to be inserted. I assume the AccountId is set through myContact.clone(false, false, false, false); which is actually not a surprise. At the same time we're assigning myNewContact.Account to virtualParentAccount - this is why the error occurs.

Unfortunately, re-assigning myNewContact.AccountId to null will not do the trick - I already tried this.

My Question: How can I circumvent this error? Is it possible to override myNewContact.AccountId which has been set through the clone method?

Any help is appreciated!

1

You don't need an External ID for this - you can use a Map of original account IDs to the cloned accounts. The important point is that Salesforce will populate the new IDs in the cloned accounts after you've inserted them, so you can reference them in the map.

(Also note that you should set isDeepClone to true when cloning)

Map<Id, Account> acctMap = new Map<Id, Account>();
for (Account acct : originalAccts) {
    Account clonedAcct = acct.clone(false, true, false, false);
    acctMap.put(acct.Id, cloneAcct);
}
insert acctMap.values();

Once you've inserted the cloned accounts, it's easy to clone the contacts and link to the new account IDs by referencing the map.

List<Contact> contactsToInsert = new List<Contact>();
for (Contact con : originalContacts) {
    Contact clonedContact = con.clone(false, true, false, false);
    clonedContact.AccountId = acctMap.get(clonedContact.AccountId).Id;
    contactsToInsert.add(clonedContact);
}
insert contactsToInsert;
  • Thanks David! I tried it and it works. – David Dec 1 '19 at 11:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.