Apex Trigger – Fixing Sobject.isSet() Not Working with Trigger Sobjects

fieldsnullsobjectsoql

I'm having an issue with the Sobject method "isSet()". It works well if I query for a record or create a record outright. But does not work correctly for Trigger objects. On trigger objects, isSet only seems to return true if the value for the field is not null.

E.X.

Account acc = [Select Null_Field_Test__c from Account LIMIT 1)
System.assert(acc.isSet('Null_Field_Test__c'));

Account accTwo = new Account();
accTwo.Null_Field_Test__c = null;
System.assert(accTwo.isSet('Null_Field_Test__c'));

But if I try it in a trigger

trigger test on Account (after insert, after update) {
   System.debug('is set: ' + Trigger.new[0].isSet('Null_Field_Test__c'));
}

Then I always get false until I put a non-null value into "Null_Field_Test__c". Is this just a bug? Is there any work around for this?

Best Answer

This behavior might make sense if we take a specific interpretation of the documentation for isSet(), which states (at time of writing, Winter '22)

Returns information about the queried sObject field. Returns true if the sObject field is populated, either by direct assignment or by inclusion in a SOQL query. Returns false if the sObject field is not set. If an invalid field is specified, an SObjectException is thrown.

Since we aren't querying for records in trigger context variables (TCVs for short), and aren't (ourselves) directly setting values on records in TCVs (only records in trigger.new/newmap are editable, and further only in before contexts), it's not unreasonable that isSet() is returning false.

Given that TCVs pull all object fields, I don't think it would be too helpful if isSet() would return true for fields on those records. Returning false seems to be a safe default.

I don't think there's a workaround for null fields, but besides that, a simple null check myRecord.myField__c != null would suffice.

Related Topic