5

There are 2 related objects for which I have sObject record instances created and they are yet to be inserted. I need to populate the parent ID on the children based on how they records are mapped. In this example let's get Account and Contact as the objects so that it's easier to understand my scenario.

Currently I have a map Map <Account, List <Contact>> and it's populated with new instances of account records as well as related contacts that need to be inserted.

If I add the keyset of the map into a new list and then insert the records, then debugging the map shows the records have their ID's populated as they're passed in by reference which is fair enough.

Once the DML is performed, debugging the same map again results with new re-instantiated map which has the keyset records updated with their ID's, but the values are reset to null.

Is this how it's supposed to work or is there something that I'm missing?

Map <Account, List <Contact>> accountWithContacts = new Map <Account, List <Contact>> ();

Account account = new Account();
account.Name = 'Test Account';

Contact contact = new Contact();
contact.lastName = 'Test1';

Contact contact2 = new Contact();
contact2.lastName = 'Test2';

accountWithContacts.put(account, new List <Contact> {contact, contact2});

system.debug('the map' + accountWithContacts);
// DEBUG|the map{Account:{Name=Test Account}=(Contact:{LastName=Test1}, Contact:{LastName=Test2})}

List <Account> accounts = new List <Account> ();
accounts.addAll(accountWithContacts.keySet());
insert accounts;

system.debug('the map' + accountWithContacts);
// DEBUG|the map{Account:{Name=Test Account, Id=001O000000HpiNPIAZ}=null}

1 Answer 1

5

Using SObjects as a key means they can't be altered. This is because the record is hashed, and changing the contents changes the hash. Instead, simply use a List<List<Contact>>. The list of accounts will maintain index order on insert, so the multidimensional list will maintain meaningful order as well.

2
  • Hi, I have this same scenario but I dont understand your solution. Map<Contact, String> conToUpsertMap; Upsert new List<Contact>(conToUpsertMap.keySet()); after insert I loos the mapped string. How should I change my map structure?
    – user8310
    Commented Jun 6, 2017 at 7:05
  • @user8310 Using two lists would suffice in your case. Contact[] recordsToInsert = new Contact[0]; String[] values = new String[0]; ... insert recordsToInsert; for(Integer i = 0, s = recordsToInsert.size(); i < s; i++) /* recordsToInsert[i] matches values[i] */ If you need more exposition, consider asking a new question so we have more space to work with.
    – sfdcfox
    Commented Jun 6, 2017 at 13:14

You must log in to answer this question.

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