0

I came across a weird behaviour of which I don't know why it happens. Maybe you guys can help me:

Setup:

I have a list of records, over which I iterate (list name: fieldAutomations). Each iteration searches for a record in a Map, creates a new SObject-record and updates a field in this record. This record is then saved in a SObject-Set called 'updateFields'.

It is possible that different iterations of fieldAutomations find the same record in the map.

After all records have been iterated through, the 'updateFields'-Set is inserted into a list which is then eventually used to update the records.

Question 1: When I have a record in my SObject-Set 'updateFields' where the value in field A has changed, and the same record is written to the 'updatedFields'-Set with a changed value in field B, it overwrites the first object. However, in the debugs it shows that both fields (A and B) were changed to the new values. Why does it do that?

Question 2: After the iteration through the records, the set is inserted into a newly created list which is then used to update the records. However, when there are two changes in the same record but only one item is in the set (because duplicates are not allowed), and I insert the set into the new list, There are two records with the same Id in the list. Which leads to an error on update.

Here is the (important part of the) code:

Map<String,SObject> objects = new Map<String,SObject>();
    Set<SObject> updateRecords = new Set<SObject>();

    for (cs_Field_Automation__c fieldAutomation : fieldAutomations) {
        System.debug('updateRecords (first): ' + updateRecords);
        // get record from objects map
        SObject record = objects.get(fieldAutomation.Object_Name__c);

        // Some logic happens here

        // update field 

        record.put(fieldAutomation.Field_Name__c, fieldAutomation.New_Value__c);

        updateRecords.add(record);

    }

    if (updateRecords.isEmpty() == false) {
        System.debug('updateRecords (Set): ' + updateRecords); // here, only one item is in the set
        List<SObject> updateRecordsList = new List<SObject>();
        System.debug('updateRecordsList (List): ' + updateRecordsList); // list is empty
        updateRecordsList.addAll(updateRecords);
        System.debug('updateRecordsList (after insert of set): ' + updateRecordsList); // lsit has two items with the same Id
        return updateRecordsList;
    } else {
        return null;
    }

This is part of the debug log that shows how there are two items in the list that was filled with te set that only had one item:

|USER_DEBUG|[903]|DEBUG|updateRecords (Set): {Account:{Id=0011t00000x3PiaAAE, Name=Testaccount, Website=null}, Opportunity:{Id=0061t00000JCcfEAAT, Name=Test Opportunity, StageName=Closed, CloseDate=2019-09-24 00:00:00, AccountId=0011t00000x3PiaAAE}} |USER_DEBUG|[905]|DEBUG|updateRecordsList (List): () |USER_DEBUG|[907]|DEBUG|updateRecordsList (after insert of set): (Opportunity:{Id=0061t00000JCcfEAAT, Name=Test Opportunity, StageName=Closed, CloseDate=2019-09-24 00:00:00, AccountId=0011t00000x3PiaAAE}, Opportunity:{Id=0061t00000JCcfEAAT, Name=Test Opportunity, StageName=Closed, CloseDate=2019-09-24 00:00:00, AccountId=0011t00000x3PiaAAE}, Account:{Id=0011t00000x3PiaAAE, Name=Testaccount, Website=null})

1

You are getting this error because you used Set<SObject> without fully understanding the mechanics of it, which is why I usually recommend against this structure entirely. Instead, you should use Map<Id, SObject>. For the former data structure, you only get deduplication if every field matches. For the latter data structure, you get deduplication if and only if Id matches.

0

Set in Apex doesn't rely on Id value for duplication reduction. You can add multiple records with same Id in a set if there is a difference between the values for those records.

eg:

Account acc1 = new Account(Id='001000000000001AAA');
Set<Account> accSet = new Set<Account>();
accSet.add(acc1);
acc1 = new Account(Id='001000000000001AAA', Name='Jar');
accSet.add(acc1);
System.debug(accSet.size()); //Prints 2

I would suggest use of Map<Id,Sobject> instead, as the key is primitive Id , which wont change during the course of operation.

  • But still not sure how an additional element got added to list. If you see the debug of set, it says it only has 1 element, but when added to list, an additional element is displayed in logs. – Vijay Ganji Sep 24 at 16:04

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.