[SalesForce] Pros and cons of generic SObject list vs multiple lists of objects

For one of the requirements I have to write code to update multiple records of different objects. Originally I was planning to do the obvious: get needed records, change some value, update these lists, but then I though… Why don't I just use a list of generic SObject?

Then I tried to find some pros and cons of using List<SObject> vs. multiple lists per object type and I could only find one:

  • Only 1 update needed for all records(= less DML operations)

Example code:

List<Opportunity> opps = [SELECT Id, OwnerId, Name FROM Opportunity WHERE Name LIKE :nameString AND OwnerId IN :fromUsers];
List<Lead> leads = [SELECT Id, OwnerId, Name FROM Lead WHERE Name LIKE :nameString AND OwnerId IN :fromUsers];
List<SomeCustomObject__c> objs = [SELECT Id, OwnerId, Name FROM SomeCustomObject__c WHERE Name LIKE :nameString AND OwnerId IN :fromUsers];
// do something with these lists, based on the requirements
update opps;
update leads;
update objs;

But this will require 3 DML operations(+any other triggered by triggers/processes/workflows). But we could simply replace the 3 DML operations by the following:

List<SObject> allRecordsToUpdate = new List<SObject>();
allRecordsToUpdate.addAll((List<SObject>)opps);
allRecordsToUpdate.addAll((List<SObject>)leads);
allRecordsToUpdate.addAll((List<SObject>)objs);
update allRecordsToUpdate;

I know, that in this case we only save 2 DML operations, but once we will need to update 10, 20, 30, whatever… different objects it might be a lifesaver.

So the question is: what are the pros and cons of using List<SObject>?

Best Answer

For cons, using SObject instead a concrete type restricts the usage of upsert by external ID, and you can't upsert generic SObject lists (the variable may be SObject[], but the actual list in memory must be a concrete type), and reduces the maximum number of records per operation to 2,000 by a feature known as chunking.

For pros, it reduces CPU usage slightly and reduces DML operations that count towards the limit (but not the row counts). Keep in mind, though, that this method is also limited to 10 "chunks" of data when you mix types.

A chunk is a consecutive run of up to 200 records of the same type. So, if you had 201 opportunities, 50 accounts, and 425 contacts, that would be a total of 6 chunks of the allowed 10, assuming all of the records were next to each other.

In practice, this is rarely a problem, but you might run into this issue if you've got alternating records, such as Account, Contact, Opportunity, Account, Contact, Opportunity...

For upsert, the following is allowed:

SObject[] a = [SELECT Id FROM Account];

But the following is not:

SObject[] a = new SObject[0];
a.addAll([SELECT Id FROM Account]);

When doing upsert on a list, each set of inserts or updates, in groups of 200, count as a chunk. The 10 chunk limit applies here as well.

Related Topic