Summer’17 :: Retrieve and Deploy Metadata through Apex

by Sudipta Deb | Apr 29, 2017 | Advanced Apex, Apex, Custom Metadata, Metadata, New Features, Salesforce Release, Summer17 | 4 comments


In Salesforce World, Metadata plays a very important role. Metadata types and components are used to represent org specific configuration and customization. Salesforce is having a very good page explaining Metadata. Here is the link – “An Introduction to Force.com Metadata“. 


Before Summer’17 release, in order to access Metadata, you need to use the Metadata API, but now Salesforce comes up with Metadata namespace. You can use classes in Metadata namespace to access Metadata components through Apex.

Why do I need to access Metadata?
Salesforce documentation explains it correctly and here are the possible reasons why you may need to access Metadata.
In this post, I am going to explain how you can access and deploy Metadata changes through Apex with an example.

Example –
In my Salesforce Org, I have one Custom Metadata Type named – “Admin Preference” which is –
The values of this Custom Metadata Type are –

Now I will create a simple VisualForce Page which will retrieve this Metadata Values and display them. At the same time from the same page, I will change the values. 

To implement this requirement, I will use the Salesforce Summer’17 New Feature – classes Metadata namespace.

Let’s Start –
In order to store the Custom Metadata Values, I will use the below class –

public class MetadataHelper{
public String name {get;set;}
public Boolean isEnabled {get;set;}

public MetadataHelper(String name, Boolean isEnabled){
this.name = name;
this.isEnabled = isEnabled;
}

public String getFullName(){
String fullName = 'Admin_Preference__mdt.';
if(name.equalsIgnoreCase('Process Builder Preference')){
fullName = fullName + 'Process_Builder_Preference';
}else if(name.equalsIgnoreCase('Trigger Preference')){
fullName = fullName + 'Trigger_Preference';
}else if(name.equalsIgnoreCase('Validation Rule Preference')){
fullName = fullName + 'Validation_Rule_Preference';
}else if(name.equalsIgnoreCase('Workflow Preference')){
fullName = fullName + 'Workflow_Preference';
}
return fullName;
}
}
How to retrieve the Custom Metadata Types and it’s Values: 

To retrieve the Custom MetadataTypes, the command is – Metadata.Operations.retrieve(). This method will retrieve the Metadata synchronously. We need to pass the list of component names and this method will return a list of matching component data (Metadata.Metadata format).

Once you have the list, power is completely in your hand. Trust me!! Really you have all the power you need then. You can iterate through the list and get the each CustomMetadataRecord. Now each CustomMetadataRecord is having CustomMetadataValues which also you can fetch and play around. 
CustomMetadataValues are stored in two fields – the first one is “field” which stores the API name of the field and the second one is “value” which stores the value of that field for that CustomMetadataRecord. Confused??? Don’t worry I will give you now a clean picture which helped me to understand and I hope it will help you as well.

To understand how the custom metadata information is stored in Salesforce, consider our Custom Metadata Type mentioned above – Admin Preference. And let’s consider one value here – 




So according to the above example – Metadata.Operations.retrieve() will retrieve the CustomMetadataRecord – Process Builder Preference. Now this record is having the label – “Process Builder Preference“, which we can get from the label field. The fullName of this record is – “Admin_Preference__mdt.Process_Builder_Preference” which we can get from the method getFullName(). 
In the above example, this CustomMetadata is having only one value which is stored inside a field of type Metadata.CustomMetadataValue. For that single  Metadata.CustomMetadataValue, the field = ‘Enabled__c” and value = true.

So the visual representation of the flow is –



With the above explanation, here comes to code –


How to deploy Custom Metadata Types and it’s Values: 
The method Metadata.Operations.enqueueDeployment is used to deploy the changes to the org. The operation is happening in asynchronous mode and that is the reason we need to provide a callback method to handle the success/failure scenarios. To create the callback, we need to implement the interface Metadata.DeployCallback and by doing that we need to put our logic in the method – handleResult.

Below is the CallBack method –


Now to deploy the changes below is the code –


You can find the full code in my Github repository.

With all these changes, below is how the functionality working – 


Limitation – Metadata access in Apex is currently only possible for custom metadata records and page layouts. You can retrieve, create or update custom metadata, but you cannot delete metadata through Apex.

Written by

Related Posts

New Apex Method | Extracting Picklist Values Based on Record Type Inside Apex

New Apex Method | Extracting Picklist Values Based on Record Type Inside Apex

For years, Salesforce developers have faced a common challenge: programmatically retrieving picklist values that are specific to a certain Record Type directly within Apex. The “solutions” often involved either complex SOQL queries against metadata, relying on the UI API (with its associated callout limits and serialization overhead), or maintaining clunky custom metadata/settings.

Good news, Technical Potpourri readers! The Salesforce Spring ’26 release is bringing a game-changer that will significantly simplify your Apex code and improve performance: native Apex methods to filter picklist values by Record Type!

read more...
Apex Cursor and Its Advantages Over Batch Processing

Apex Cursor and Its Advantages Over Batch Processing

Struggling with large datasets and SOQL governor limits in Salesforce? In this video, I will dive deep into Apex Cursors, the powerful new feature that revolutionizes how we process millions of records.

Apex Cursors allow developers to navigate through query results in manageable chunks within a single transaction or across Queueable jobs. In this video, I will show you the correct way to implement Apex Cursor and also when this is an exception, how to handle that and perform retry.

read more...

4 Comments

  1. Mohit Bansal

    Anyone looking for Salesforce app which save their time and can perform bulk CRUD operations in few click – their search end at Salesforce Appexchange app Bulk Object Field Creator
    Most recommended and appreciable app by Salesforce MVP

    Reply
  2. Ankit Bansal

    Hi,

    There is a Salesforce tool formally known as migSO a Salesforce Metadata Migration App, that helps admins or developers to clone Reports, Objects, and Fields within the same or External Salesforce Org in a few clicks.

    Reply
    • Sudipta Deb

      Thank you for letting us know Ankit about the tool.

      Reply

Leave a Reply