12

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.

4
  • 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. Jun 16, 2016 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, 2016 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. Jun 16, 2016 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?
    – Edmondo
    May 13, 2017 at 12:40

2 Answers 2

6

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').

2

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
1
  • Using sObject.get(field) is a viable workaround. Jun 21, 2016 at 1:54

You must log in to answer this question.

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