I'm trying to selectively delete an SObject's field histories based on the members of an sobject's fieldset (think PII deletion - feature available V42).

Example: OOTB Order with field set containing:

  • BilltoContactId
  • Custom_Lookup__c
  • My_Decimal_Field__c

Well, it turns out that this query (generated from the fieldset's members' fieldPath):

Select Id, Field From OrderHistory 
  Where OrderId = '...' AND 
        Field IN 

will not return any records where BillToContactId changed (and yes, field history tracking is enabled on that field)

It appears that ...

  • For an OOTB SObject lookup to an OOTB SObject, the lookup field's fieldpath in the fieldSet is xxxId but the value of the Field column in the xxxHistory object is simply xxx. Example: BilltoContactId in fieldset but BilltoContact in OrderHistory.Field.
  • For custom SObjects, a lookup field's fieldpath in the fieldset is yyy__c and the value of the Field column in the xxxHistory object is also yyy__c. Example: Custom_Lookup__c in both fieldset and OrderHistory.Field.

So ... what to do?

Option 1

  • Code a bit of heuristics using the field's describe and, if !isCustom() and !getReferenceTo().isEmpty(), then strip ID off the field API name to get a xxxHistory-queryable Field value.

Option 2

Is there something more robust?

  • 1
    I'm not sure it's more robust (cf. this unanswered question) but using getRelationshipName() on the field describe seems to always return that core element of the name for a standard lookup. I don't know that it's documented anywhere that that's the case, but this whole shindig seems to be outside the reach of documentation.
    – David Reed
    Feb 27 '19 at 0:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.