11

I have a custom object with a couple of checkbox fields. Those fields have a Default Value of "Unchecked".

How should those fields behave when assigned a null value in Apex?

Simplified example code:

Boolean nullBoolean;
System.assertEquals(null, nullBoolean, 'Expected to be null');

RepType__c rt = new RepType__c();
// Assign the checkbox fields from the variable
rt.IsOrderManagerRepType__c = nullBoolean;
rt.IsAccountManagerRepType__c = nullBoolean;

// Expected to be null, but comes back as false (the default value?)
System.debug('Direct field value: ' + rt.IsAccountManagerRepType__c); 
//System.assertEquals(null, rt.IsAccountManagerRepType__c, 'This assertion will currently fail');

// Shows that the checkbox fields are null
System.debug(rt);
// Confirms checkbox fields are null, not false
System.debug(JSON.serializePretty(rt)); 

insert rt;

Basic Debug output:

Direct field value: false
RepType__c:{IsOrderManagerRepType__c=null, IsAccountManagerRepType__c=null}

JSON debug output:

{ "attributes" : { "type" : "RepType__c" }, "IsOrderManagerRepType__c" : null, "IsAccountManagerRepType__c" : null }

Exception from insert:

System.DmlException: Insert failed. First exception on row 0; first error: INVALID_TYPE_ON_FIELD_IN_RECORD, IsAccountManagerRepType: value not of required type: : [IsAccountManagerRepType__c]

Note how any direct code access to the checkbox field in Apex gives the value as being false. So if I check it in code it looks fine to insert. However, the debug of the entire object and attempts to use it in DML show the null value.

  • 1
    That is isn't symmetric in the handling of null values makes me think this is a bug. I've raised case 14025277 for it. – Daniel Ballinger Jun 16 '16 at 21:28
  • 1
    sobject checkbox fields will be nillable:false so one could argue they shouldn't be assigned null :-). But I would agree with your assertion that an sobject field should be treated like any other apex variable when it comes to null and not masquerade as false – cropredy Jun 16 '16 at 22:02
  • 1
    It certainly wasn't my intention to assign null to them :). I was getting the value from the web service that returned a Boolean and assigning it directly to the custom object. Then I started getting problems during the upsert when the ws returned null. I added all sorts of assertions and checks in the code to make sure the value was true or false. The assertions looked fine, but the insert still failed. Had me scratching my head for a bit. – Daniel Ballinger Jun 16 '16 at 22:21
  • So it is impossible to insert an object which has a checkbox field neither true or false (a nullable Boolean, basically). Is that right? – Edmondo1984 May 13 '17 at 12:40
5

Answer from support for Case #14025277

R&D has confirmed that this is a documentation issue. The documentation will be updated to clarify this behavior (please see below).

"The expression accessing a Boolean type field on an sObject with simple dot notation is evaluated to true only if the field value is non-null and true. Otherwise it is evaluated to false."

As you may already know - To check the checkbox value when using null, please use sObj.get('fieldname').

1

I think all of this comes from a fact that Boolean in Apex can have 3 values while Checkbox in database can have only two. Some of the outputs are really questionable.

I would propose to use fact that JSON has correct value to check where we actually are:

 rt.IsOrderManagerRepType__c = nullBoolean;
 system.debug(rt.IsOrderManagerRepType__c!=null);          //true
 system.debug(rt.get('IsOrderManagerRepType__c')!=null);   //false
  • Using sObject.get(field) is a viable workaround. – Daniel Ballinger Jun 21 '16 at 1:54

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.