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.
1.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();
2.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();
}
}
Custom MetaData Types
Custom MetaData Types change a lot of things about custom settings. In my mind, the biggest advantage is that the data is deployable and can be managed by a package or by developers without having to write code or sign into the production org and manually set values. This means that the values aren’t really data, they’re metadata and it’s a fantastic improvement for developers and admins. Most Salesforce orgs have dozens or hundreds of custom objects or custom settings that handle configuration. A lot of the time these changes are manually migrated from a sandbox or developer org.
For the most part, custom metadata can do everything that a list custom setting can do. The two downsides that I am aware of are that there’s no native support to create or modify the records within the apex language. I believe this is currently on the roadmap for Salesforce to deliver at some point.
The other downside is that the Custom MetaData Type must be queried unlike the List Custom Setting. Thankfully, the SOQL queries for the custom metadata types don’t count against the number of soql queries.
Common Usages
For most situations, where you used a list custom setting you can probably use custom metadata types. The only caveat with that is they can’t Create Update or Delete done on them without using the MetaData API. For developers working on managed packages, they are a fantastic replacement for storing anything that doesn’t need to be updated by the apex. During the installation process, there’s also no need to write any code to initialize them because the values are deployed with the package.