0

I am trying to update one of the related objects once the Account merge is completed.

Database.MergeResult results = Database.merge(masterAcct, duplicateAcct, false);

getUpdatedRelatedIds() method from the MergeResult class is giving me all the related Ids as List<String> but I want to filter a specific object from the list and update that record. So far I could only think of this way but let me know if there's a better way to do the same.

    List<String> returnedIds = new List<String>{'a812f000000CnFqAAK','a262f000000ndRnAAI','0012f00000lnY0rAAE'};
    List<Id> usefulIds = new List<Id>();
    for (String s : returnedIds)
    {
        if (String.valueOf(Id.valueOf(s).getSObjectType()) == 'UseFulObject__c'){
            usefulIds.add(s);
        }
    }
List<UseFulObject__c> updateUsefulRecords = new List<UseFulObject__c>();
    for (Id s: usefulIds){
        UseFulObject__c uo = (UseFulObject__c) s.getSObjectType().newSObject(s);
        uo.IsActive__c = false;
        updateUsefulRecords.add(uo);
    }
    
    update updateUsefulRecords ;
5
  • Code readibility wise, this approach looks fine.
    – Raul
    Jul 27, 2022 at 13:41
  • @Raul How about performance wise? Would there be an impact if the returnedIds are in 1000s?
    – SunnyG
    Jul 27, 2022 at 13:46
  • Code looks good to me, although if you can reduce the second for loop. Add the logic in the first for-loop if criteria.
    – Piyush
    Jul 27, 2022 at 14:05
  • @Piyush Did you mean something like this? if (Id.valueOf(s).getSObjectType() == UseFulObject__c.SObjectType){ UseFulObject__c sa = (UseFulObject__c ) Id.valueOf(s).getSObjectType().newSObject(Id.valueOf(s)); sa.IsActive__c = false; sa.Name = sa.Name+'_MERGE'; updateUsefulRecords.add(sa); }
    – SunnyG
    Jul 27, 2022 at 14:45
  • @SunnyG Yes, This way you can reduce for loop.
    – Piyush
    Jul 27, 2022 at 14:54

2 Answers 2

4

What you have already looks good. The only optimization I see is you can just compare the token directly, you don't need String.valueOf.

if (Id.valueOf(s).getSObjectType() == UsefulObject__c.sObjectType)
1
  • Didn't know about that, thanks.
    – SunnyG
    Jul 27, 2022 at 14:21
2

In addition to the simplified type check that @Adrian Larson pointed out, you can also change:

UseFulObject__c uo = (UseFulObject__c) s.getSObjectType().newSObject(s);
uo.IsActive__c = false;
updateUsefulRecords.add(uo);

to:

updateUsefulRecords.add(new UsefulObject__c(Id = s, IsActive__c = false));

There's no need to be jumping hoops to work out what to create given that you hard-coded the type cast anyway, and setting all necessary fields in an SObject constructor is slightly more efficient (it depends just how many fields you need to set on how many records really).

6
  • 1
    Setting fields in the SObject constructor takes less of the CPU limit, but the difference is miniscule. Like 0.016 vs 0.024 CPU per field-record. That's a maximum of 80 CPU limit for 10k records. Getting rid of the getSObjectType().newSObject() probably has more of an impact, but at the cost of some flexibility (though OP would need to use a List<SObject> and SObject's .set(), and sort the list prior to dml, and not hard-code the SObject type to get full flexixbility).
    – Derek F
    Jul 27, 2022 at 15:00
  • Is there a way to retain field values of existing record by passing the Id ? I am only updating boolean property at this point but If I want to append to a prior value of a text field, is that something possible with this implementation? Or I have to query to do so?
    – SunnyG
    Jul 27, 2022 at 16:24
  • @DerekF the OP makes no mention of needing "flexibility" so my suggested change is only for the better (even if you picked up more on the performance aspect of the constructor than on the avoidance of use of s.getSObjectType().newSObject(s) which was my primary change. I guess I should have provided my explanation in the opposite order.
    – Phil W
    Jul 27, 2022 at 16:40
  • @SunnyG you can always query the original records with the required text field and then use that as part of your update. The 'only setting the fields I really need to update' approach you have used is definitely correct; if you include irrelevant fields you risk causing lost of concurrent changes to those fields otherwise.
    – Phil W
    Jul 27, 2022 at 16:42
  • 1
    @DerekF That test you linked was written incorrectly. Limits.getCpuTime() is grossly inaccurate for profiling Apex, DateTime.now().getTime() is much better. The actual cost of dot notation is indeed about 2x, and that cost can be significant depending on the number of fields you need to set.
    – sfdcfox
    Jul 27, 2022 at 16:53

You must log in to answer this question.

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