How to Use Salesforce Custom Settings

Sharing is Caring

When developing on Salesforce’s force.com platform it’s essential to avoid hardcoding application settings because a deployment will be required every time something needs to be changed. Application Settings could be anything really, but often it’s things like an email address, ip address, or even a passkey. For those not already aware, a Salesforce deployment can take hours to finally happen which may cause significant downtime in some businesses.

What’s a Custom Setting in Salesforce?

In the past, Salesforce customers were using custom objects to store application settings and other metadata. Whenever a page loaded, or a process was occurring a SOQL query needed to be done to get whatever the setting was. Naturally, this could cause things to load slowly and for different limits to be hit in apex (ie SOQL queries.) Basically, companies were storing things like MCC/Sic Codes, Country Codes, and other values that rarely ever change as custom data and then routinely querying the values. This custom data could only ever really ever be used in apex code.

Custom settings changed all of this. Custom Settings are basically custom objects that are available from the applications cache, so there’s no need to do a SOQL query to get the value. Custom settings are a vast improvement over just using custom objects because there’s no SOQL Query, there’s very few limits, and they can be used pretty much anywhere. Hierarchical custom settings can be used in formula fields, validation rules. All types of custom settings can be used in apex code which allows them to be incredibly powerful.

Salesforce has a couple of different types of custom settings available: list, hierarchical, and custom metadata. I’m considering custom metadata to be a custom setting although I’ve heard some in the community say that it isn’t. In my experience, Custom MetaData is an excellent replacement for the List Custom Setting.

List Custom Setting
List Custom Settings were introduced several years ago. They were the first iteration of custom settings, basically they allowed companies to avoid using custom objects as a way to store meta data and introduced an application cache. As mentioned previously, they avoid the overhead of having to query and avoid counting against the SOQL limits. For the most part, I am rarely using List Custom Settings anymore and instead preferring to use the newer Custom MetaData Type. Currently, it’s not very easy to write Apex to update a custom metadata type, so in those cases I recommend using a List Custom Setting.

Accessing a list custom setting is pretty easy because of the instance methods that Salesforce has provided. For example, say we had a list of SIC/MCC codes that we had saved into a custom setting called SIC_Codes__c. In the name field, we are storing the actual code, and then we have another field called Official_Name__c, and finally another field called Short_Description__c.

If we wanted to get the different values for 1521, which is a general contractor we could do the following:

	SIC_Codes__c code = SIC_Codes__c.getInstance('1521'); 
	system.debug('the official name is' + code.Official_Name__c)

Even more useful, is the fact we can also get back all of the possible options as a Map. To do that, using the exact same list custom setting we could do this:

	Map<string, SIC_Codes__c> codes = SIC_Codes__c.getAll(); 
	
	//iterate through the map and show all of the official names.
	for (string key: codes.ketset())
	{
		SIC_Codes__c code = codes.get(key);
		system.debug('the official name is' + code.Official_Name__c)
	}

As mentioned previously, the List custom setting was normally used as a list of custom objects that rarely changed. It’s also possible to get all of the custom settings as a list by taking advantage of the fact that .get() returns a map. I used this pattern very frequently for countries, and SIC codes.

List<SIC_Codes__c> codes = SIC_Codes__c.getAll().values(); 

Hierarchical Custom Setting
For the most part, I found I use the hierarchical custom setting most frequently. There’s a few different ways that it can be used. In the first example, we’ll use it in a way similar to the List Custom Setting. Here’s one way that you could use a Hierarchical custom setting for getting url for an API.

public string getUrl()
{
	MyRemoteAppSettings__c settings = MyRemoteAppSettings__c.getInstance();
	return settings.AccessUrl__c;
}

As you have likely noticed, the custom setting methods are called by and operate on a particular custom setting. The methods have some difference between Lists and Hierarchical Custom Settings. The Hierarchical Custom Setting actually conceals some significant differences that can be utilized. In a hierachical custom setting, it’s possible to have different values returned based on the organization, profile, and user.

Hierarchical custom settings allow values at any of three different levels:

  1. Organization, the default value for everyone
  2. Profile, which overrides the Organization value
  3. User, which overrides both Organization and Profile values

In our above example, we didn’t provide an Id or Name or anything in the getInstance() call so the call would default to whatever the User Settings are set to. If the User Settings aren’t set, it would then default to what the Profile Settings are set to, and then finally it would default to what the Organization Settings are set to. There’s a bit of a trick to this as well, if one field isn’t set it may use the next tier’s value, and so on.

This difference allows us to use the Hierarchical custom setting pretty much everywhere and in some pretty clever ways. Hierarchical Custom Settings can even be used in a formula. I use it the exact same way that I used App.Config Application Settings in C#.NET.

In a visualforce page, we can allow a section to only be rendered for a certain profile or for the org, etc. To do this we use the $Setup object, and then reference our custom setting and then finally our field.

So for a custom setting called MyAppSettings, and a field of Show_Example_Panel__c we would do this:

<apex:outputPanel id="examplePanel" rendered="{!$Setup.MyAppSettings.Show_Example_Panel__c}">
 Some content...
 
 </apex:outputPanel>

In an apex trigger, we could use the Hierarchical Custom Setting as a Trigger kill switch for a particular user or profile.

trigger TriggerKillSwitch on Account (after update, after insert) {
	if (MyRemoteAppSettings__c.getInstance().RunAccountTrigger__c == true)
	{
		AccountTriggerHandler.doSomething();
	}
}

To make things even more interesting, Hierachical Custom Settings also have other methods that allow us to look at only a certain tier. Let’s say, we don’t want to run for the whole organization instead.

trigger TriggerKillSwitch on Account (after update, after insert) {
	if (MyRemoteAppSettings__c.getOrgDefaults().RunAccountTrigger__c == true)
	{
		AccountTriggerHandler.doSomething();
	}
}

Notice how I used the getOrgDefaults() method ?

Testing
One of the biggest things to remember when writing tests against apex code or triggers is to remember that the custom settings will be null unless a value has been set. You should really write two different tests. A test for when the custom setting has been given a value or when the custom setting has no defined value (it’s null.)

In Spring 15, Salesforce finally added a method that can be executed before each test is run. This blog post about the @testSetup annotation covers that in some more detail. By convention, I always call my testSetup method CreateTestData.

Custom MetaData Types

Salesforce has recently released some changes that give developers even more control and are a great alternative to custom settings called Custom Metadata Types which resolve a lot of the issues that ISV Developers had with custom settings. In a lot of ways, the Custom MetaData Types are revolutionary. The biggest advantage is that the values are deployed as part of a change set or part of a package installation. This means that developers or admins no longer necessarily need to manually add values or write code to manually add values. For a Salesforce ISV with a very large application, this could be a very large savings in development time.

Check out this blog post regarding Custom MetaData Types and why they will replace list custom settings, and maybe even Hierarchical Custom Settings.

Sharing is Caring

Brian is a software architect and technology leader living in Niagara Falls with 13+ years of development experience. He is passionate about automation, business process re-engineering, and building a better tomorrow.

Brian is a proud father of four: two boys, and two girls and has been happily married to Crystal for more than ten years. From time to time, Brian may post about his faith, his family, and definitely about technology.

3 Comments

  1. Nice, well-written article on custom settings Brian. The one piece that seemed to be missing was testing code that uses custom settings, which aren’t always accessible from within a test class and may need to have a new instance created when that happens. Will look forward to reading what you have to say about custom metadata. I’ve been debating on whether to start implementing it with some of my non-ISV code. It doesn’t seem nearly as easy to access.

    • Hi Cal,

      Thanks for taking the time to comment.

      I’ve added some detail about testing, and will add some examples probably later today. I have been using Custom MetaData instead of lists wherever I can be sure I don’t have to update the value. Right now, to update the value you need to use the MetaData API which makes it pretty challenging.

      • Yes, that’s the challenge with custom metadata. Even when using Andrew Fawcett’s wrapper, there’s not a “simple & easy” way to quickly access it from Apex like there is with custom settings. Hopefully, Salesforce will rectify that situation sometime in the near future but I doubt that it’s anywhere near the top of their priority list.

Comments are closed.