A list of objects should be inserted in the order it is populated, so lower indexes will be inserted first. This is important when dealing with a List<sObject>
where you rely on the order within the list to prevent excessive chunking.
My question is whether the above statement holds true on upsert
.
The code below assumes a Test__c
object with one unique value text field named unique_field__c
(obviously just an example).
// create a record with a unique value set and insert it (will get updated later)
Test__c test1 = new Test__c(unique_field__c = 'a');
insert test1;
// create a record with the same unique value, but don't save it (will get inserted later)
Test__c test2 = new Test__c(unique_field__c = 'a');
// edit the unique field on the persisted record
test1.unique_field__c = 'b';
// fill a list with the two records above, the existing one first
List<Test__c> testList = new List<Test__c>{test1, test2};
// try to upsert the list -> duplicate value error occurs
upsert testList;
The expected behaviour, based on how insert is processed, would be to update the first record, changing its unique value field, then inserting the second record, which at this moment can take the value because it's not used by the first one any more. Obviously, this doesn't happen. Either inserts are executed first or validation is done in advance.
Can someone confirm where the problem lies?
Btw, I know there are simple ways to work around this, but it intrigues me because my understanding of the order of execution is lacking.