Accessing record type IDs in Apex code

Where you use record types on several objects, a convenient way to obtain the record type ID in Apex is needed. And as the record type ID requires a SOQL query to obtain the org-specific value, governor limits and efficiency come in to play too.

The pattern illustrated below allows the ID to be obtained using this simple and flexible call:

Id id = RT.getId(cve__Claim__c.SObjectType, RT.Name.ShortTermDisability);

The benefits of this approach are:

  • Only one SOQL query done (per server request) no matter how many record type IDs are referenced or where they are referenced e.g. inside a loop.
  • Avoids problems of typos in strings by using the compile-time checked SObjectType field and an enum for the Name values.
  • Handles the case where multiple objects use the same record type name well.
  • Adding a new record type just requires a single line to be added to the Name enum.
 * RT stands for "RecordType".
 * Named cryptically as typical usage includes this class name twice.
public class RT {
     * These (developer) names can apply to more than one SOBjectType.
    public enum Name {
    private static final String SEPARATOR = '::::';
    private static Map<String, Id> CACHE;
     * Get the Id that can be set on or compared with an SOBject's RecordTypeId field.
     * Backed by a cache of all record type ids for the duration of a request.
    public static Id getId(SObjectType sobType, Name developerName) {
        if (CACHE == null) {
            CACHE = new Map<String, Id>();
            for (RecordType rt :  [
	                select Id, SObjectType, DeveloperName
	                from RecordType
	                where DeveloperName in :getNames()
	                ]) {
                CACHE.put(rt.SObjectType + SEPARATOR + rt.DeveloperName, rt.Id);
        return CACHE.get(String.valueOf(sobType) + SEPARATOR +;
    private static Set<String> getNames() {
    	Set<String> names = new Set<String>();
    	for (Name name : Name.values()) {
    	return names;

Also check out GaryB’s Record Types approach.


7 thoughts on “Accessing record type IDs in Apex code

    • As this is a common problem I’m not surprised that others have also solved it…

      The key difference is that I’m using SOQL and the code you link to is using Schema.getGlobalDescribe(); not sure which is better. I do think its worth using compile-time checked types like SObjectType and enum in APIs rather than strings though.

  1. I used to roll one of these classes every time I started a project, but I stumbled on this alternative which I now prefer:

    List recTypes = Opportunity.SObjectType.getDescribe().getRecordTypeInfos();

    (Similar methods are available such as getRecordTypeInfosByID that return a map for you – not 100% on the method name of that one)

    This doesn’t hit your SOQL query limit and instead counts against your “Record Type Describes” limit – 100 per transaction in EE.

    The only downside I’ve found to this is that it uses the record type’s name rather than the developer name. The developer name of a record type is much less likely to change IMO, so developer name is safer.

    • If you come from a background where static members stick around you may be surprised to learn that in Apex static members only have request scope. The point of caching them as above is for when multiple pieces of code are referencing them within one request. So there is not a problem with the cache being out of date.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s