1

I am stuck in a very strange situation. I have one custom object (test_Boolean__c) and a field of checkbox type (check_Boolean__c) whose default value is true.

Now this is what I did :- Created a record of test_Boolean__c object in a test method.

And run a code

test_Boolean__c obj = new test_Boolean__c();
insert obj;
Boolean x1 = obj.check_Boolean__c; // => true
Boolean x2 = (Boolean) obj.get('check_Boolean__c'); // => null

I am getting two different value of check_Boolean__c field.

Not getting any solution of it. I want same behavior for Boolean x2 = obj.get('check_Boolean__c'); too

3
  • The get method will return the same value or throw an "Invalid field" exception if the name is wrong. As Boolean x2 = obj.get('check_Boolean__c'); won't compile unless you include a Boolean cast, I suspect you may be reaching the wrong conclusion in your testing.
    – Keith C
    Commented Aug 27, 2015 at 10:48
  • What happens if you re-query the values from the database? I vaguely recall something about the default values being database level, so perhaps they're not available until you query the record.
    – Nick C
    Commented Aug 27, 2015 at 13:19
  • Yeah, this is what i tried minutes ago. Thank you :) Commented Aug 27, 2015 at 13:24

2 Answers 2

3

To illustrate what Keith mentioned in his comment, try running your above code in the execute anonymous window. Using a checkbox field on Account, I simulated what you are trying to do, with and without casting as Keith mentioned and with casting it definitely should work as you believe it should.

Account acctTrue = [select Match_Billing_Address__c from Account WHERE Match_Billing_Address__c = true limit 1];
Account acctFalse = [select Match_Billing_Address__c from Account WHERE Match_Billing_Address__c = false limit 1];
Boolean x1 = acctTrue.Match_Billing_Address__c; // => true
Boolean x2 = acctTrue.get('Match_Billing_Address__c'); // => null
Boolean x3 = acctFalse.Match_Billing_Address__c; // => true
Boolean x4 = acctFalse.get('Match_Billing_Address__c'); // => null

System.assertEquals(x1, x2);
System.assertEquals(x3, x4);

System.debug('x1:' + x1 + ' x2:' + x2 + ' x3:' + x3 + ' x4:' + x4);  

The above results in the error when attempted to run:
Error

However, after adding boolean casts to both lines 4 and 6:

Account acctTrue = [select Match_Billing_Address__c from Account WHERE Match_Billing_Address__c = true limit 1];
Account acctFalse = [select Match_Billing_Address__c from Account WHERE Match_Billing_Address__c = false limit 1];
Boolean x1 = acctTrue.Match_Billing_Address__c; // => true
Boolean x2 = (Boolean)acctTrue.get('Match_Billing_Address__c'); // => null
Boolean x3 = acctFalse.Match_Billing_Address__c; // => true
Boolean x4 = (Boolean)acctFalse.get('Match_Billing_Address__c'); // => null

System.assertEquals(x1, x2);
System.assertEquals(x3, x4);

System.debug('x1:' + x1 + ' x2:' + x2 + ' x3:' + x3 + ' x4:' + x4);  

You can see the results in the debug log and the asserts passed.
debug log

Update based on the comment, I believe what you need to do in your test class is load the defaults for the field, the following from the docs, should help you resolve that issue:
newSObject(recordTypeId, loadDefaults)

Constructs a new sObject of this type, and optionally, of the specified record type ID and with default custom field values. Signature

public sObject newSObject(ID recordTypeId, Boolean loadDefaults)

Parameters

recordTypeId

Type: ID

Specifies the record type ID of the sObject to create. If no record type exists for this sObject, use null. If the sObject has record types and you specify null, the default record type is used.

loadDefaults

Type: Boolean

Specifies whether to populate custom fields with their predefined default values (true) or not (false).

Return Value

Type: sObject

Usage

For required fields that have no default values, make sure to provide a value before inserting the new sObject. Otherwise, the insertion results in an error. An example is the Account Name field or a master-detail relationship field.

Since picklists and multi-select picklists can have default values specified per record type, this method populates the default value corresponding to the record type specified.

If fields have no predefined default values and the loadDefaults argument is true, this method creates the sObject with field values of null.

If the loadDefaults argument is false, this method creates the sObject with field values of null.

This method populates read-only custom fields of the new sObject with default values. You can then insert the new sObject with the read-only fields, even though these fields cannot be edited after they’re inserted.

If a custom field is marked as unique and also provides a default value, inserting more than one new sObject will cause a run-time exception because of duplicate field values.
execute anonymous example

3
  • Hello Jenny Thanks for your help, but problem is a bit different. I have a check box field, whose value is by default true. And I am doing all this stuff in a test class with seeAllData=false. so I am getting null value while using getter method. Commented Aug 27, 2015 at 12:39
  • Sorry for not mention test method. Commented Aug 27, 2015 at 12:39
  • @VivekMalpani ok, I updated my answer based on what I think your stating your issue to be.
    – Jenny B
    Commented Aug 27, 2015 at 12:50
1

I got the workaround for this

test_Boolean__c obj = new test_Boolean__c();
insert obj;
Boolean x1 = obj.check_Boolean__c; // => true
Boolean x2 = (Boolean) obj.get('check_Boolean__c'); // => null

Using this will always give a null value for standard getter method.

Use like this for getting same behavior of fetching field by using both ways.

test_Boolean__c obj = new test_Boolean__c();
insert obj;
obj = [select check_Boolean__c from test_Boolean__c limit 1];
Boolean x1 = obj.check_Boolean__c; // => true
Boolean x2 = (Boolean) obj.get('check_Boolean__c'); // => true

Means you need to reload the obj for this.

0

You must log in to answer this question.

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