March 8, 2010

Custom Settings Null Pointer Exception quick fix !

Salesforce custom settings are nice in development env. But you get Null Pointer Exception in orgs where we deploy the same code, this is because Custom Settings need at least a single record to give a valid Sobject handle for CustomSetting__c.getInstance() call.  Here is the sample scenario that covers this issue and shows solution.

Custom Setting

Screen cast show a Custom setting named “MyCustomSetting__c” created.

Custom Setting’s – Custom field

A single custom field named “Config_Field_1__c” is defined for the custom setting above. Please note that its value is defaulted to ‘Hello World’.

Code accessing Custom Setting

Here is the sample code that tries to read the value of the custom setting defined above.

System.debug('MY CUSTOM SETTING VALUE : '  + MyCustomSetting__c.getInstance().Config_Field_1__c);

Upon execution it will throw Null Pointer exception if there is no value defined at organization, matching profile or user level. The fix to this issue is simple you can add this single line of code before accessing the custom setting value.

if (MyCustomSetting__c.getInstance() == null) 
  upsert new MyCustomSetting__c (SetupOwnerId=UserInfo.getOrganizationId());

If the custom setting type is “LIST” you need to change the above one liner a little. This is because for “LIST” type custom settings Name is a mandatory attribute. Here is the code snippet.

if (MyCustomSetting__c.getInstance() == null) 
  upsert new MyCustomSetting__c (Name = ‘MyCustSettingName’, SetupOwnerId=UserInfo.getOrganizationId());

This code just creates an organization wide value for your custom setting, if that doesn’t already exists. So now accessing this code prints “Hello World” on console.

Important Notes

  • Success of the above approach depends on the way you configured your Custom Setting’s Field. Its highly recommended  you create custom setting’s fields with some intelligent default values.
  • Create a Singleton class called CustomSettingsHelper to encapsulate all custom setting’s access logic in one place. This will also give you a chance to put  this single liner code in single place, so that you don’t need to make call to this one liner before accessing any custom setting field. Here is a sample
    public class CustomSettingsHelper {
      
       /**
        The SINGLETON handle to the instance
       */
        private static CustomSettingsHelper self;
      
            
        public static CustomSettingsHelper self() {
          if (self != null) return self;
          
          // To create org wide defaults in new org automatically. This
          // will prevent NPE's in future.
          if (MyCustomSetting__c.getInstance() == null) {
            upsert new MyCustomSetting__c (SetupOwnerId = Userinfo.getOrganizationId());          
          }
          
          self = new CustomSettingsHelper();
          return self;
        }
        
        // No body needs to construct it, a single reference will suffice. 
        private CustomSettingsHelper() {      
        }
        
        // This method can be used to access the custom settings
        public String getConfigField1() {
            return MyCustomSetting__c.getInstance().Config_Field_1__c;
        }
      
        // Client Code that shows how to access the custom setting
        public static testmethod void testCustomSetting() {
          System.assertEquals('Hello World', CustomSettingsHelper.self().getConfigField1());
        }
        
    }