Press ESC to close

salesforce apex default values explained !

force.com standard and custom objects allows you to define fields with default values. Though there is a major confusion regarding usage and availability of default values in apex code. This confusion arises due to the fact that native salesforce user interface shows the default value’s pre-calculated, even before saving the record.  But in apex code this is not true, the values are not available until you save and reload the record back.

Here is a simple Sobject and a complete scenario that covers the whole story. For illustration a simple custom object named “TestObj” is created, as shown below.

This custom object has a single custom field named “DefValFld”. This field is  a date field with default value configured to be a formula : TODAY() + 7 as shown below

Now this is what that comes on salesforce native ui when “New” button is clicked, pls note that the formula is executed even before save.

So this clearly indicates that salesforce UI is pre-calculating the formula, even before save.  But if the same is tried in Apex code as follows it will not work, here is the sample code.

TestObj__c testObj = new TestObj__c();
system.debug('Value before Save : ' + testObj.DefValFld__c);
insert testObj;
system.debug('Value after Save : ' + testObj.DefValFld__c);
testObj = [select id, DefValFld__c from TestObj__c where id=:testObj.Id limit 1];
system.debug('Value after Reload : ' + testObj.DefValFld__c);

Here is the output that I got on running the code snippet above :

line 2, column 1: Value before Save : null
line 3, column 1: Insert: SOBJECT:TestObj__c
line 3, column 1:     DML Operation executed in 26 ms
line 4, column 1: Value after Save : null
line 5, column 11: SOQL query with 1 row finished in 6 ms
line 6, column 1: Value after Reload : 2010-02-01 00:00:00

So this clearly indicates that Apex Code doesn’t gets the default values calculated on creating new Sobject(). So to get the default value in your apex code, we need to reload the Sobject.  Even if some one is trying to get the default value using getDescribe() calls, the result will be the same i.e. no/null default value will be provided. The same is shown below:

// Code
System.debug(TestObj__c.DefValFld__c.getDescribe().getDefaultValue());
// Output
NULL

The reason for TestObj__c.DefValFld__c.getDescribe().getDefaultValue() getting failed is because of the fact that the record’s default field might be depending on some instance level data using merge fields. So the value can’t be calculated in a static manner like this i.e. without any instance reference. I tried default values with other field types like “text”, “number” and “date”, but there was no success using the describe call. I am not sure why salesforce gave this method 🙂

Another way to get the values for NON FORMULA based default value fields is to use “getDescribe().getDefaultValueFormula()”. This call returns the  “Returns the default value specified for this field if a formula is not used”. So for text field having default value as “Hello World” it will return the correct value, as its not using formula stuff. This still doesn’t works with PICK-Lists.

Here are some other useful facts about “SFDC Default Values” (From SFDC Knowledge base)

  • If a default value is based on the value of a merge field, Salesforce.com uses the value of the merge field at the time the default value is executed. If the value of the merge field changes later, the default value is not updated.

  • Users can change or remove the default field value on a record.

  • Default values should not be assigned to fields that are both required and unique, as uniqueness errors may result.

  • If you make an activity custom field universally required, you must also provide a default value.

  • If an activity custom field is unique, you cannot provide a default value.

  • Default field values are different from formula fields in the following ways: they are only executed once, at record creation; they are not read only; and the user can change the value but cannot restore the default field value.

  • Since the default value is inserted before users enter any values in the new record, you cannot use the fields on the current record to create a default field value. For example, you cannot create a default field value on a contact that uses the first initial and last name because those values are not available when you click New to create a contact record. However, you can use the record type because it is selected before the record edit page displays.

  • To apply a different default value for different record types, use the record type as a merge field in a CASE function within the default field value setup.

  • Fields that are not visible to the user due to field-level security are still available in the formula for a default field value.

  • Connect Offline and Connect for Outlook do not display default values. However, Salesforce.com inserts the default values when a user syncs unless the user entered a value.

  • Default field values are not available in the Self-Service portal.

  • Lead conversion, Web-to-Lead, and Web-to-Case do not execute default field values.

Comments (5)

  • Anonymoussays:

    October 4, 2010 at 6:38 am

    Here is a code sampleSchema.DescribeFieldResult F = Account.Industry.getDescribe();List pickVals = F.getPicklistValues();String defPickListVal = null;for (Schema.PicklistEntry pv: pickVals) { if (pv.isDefaultValue()) { defPickListVal = pv.getValue(); }}system.debug('Def Pick Val : ' + defPickListVal); To see some non-null value, you need to make a picklist value default first in Account's Industry field.

  • Anonymoussays:

    February 2, 2011 at 10:35 pm

    On the first point (“Apex Code doesn’t gets the default values calculated on creating new Sobject()”) the problem is that variables don't suddenly become references to actual database records when you perform DML. They remain the original, in-memory copies of the data you had before you inserted/updated your database record.Only the value of the data in a variable gets pushed to the database. This is why you can retrieve 2 fields out of hundreds, change one of those fields in memory, and then push that update to the database record without blanking out the hundreds of fields you did not pull in to memory. Anything done to a database record on insert or update, including changes made by Workflows, Apex Triggers, or just default values, happens to the database copy and not the values you are holding onto in memory.

Leave a Reply

%d bloggers like this: