When a data restore is performed in Salesforce, a new record ID is automatically generated as part of standard Salesforce functionality. This can cause issues with integrations that rely on the ID as the unique identifier. To prevent this, you can create a custom field to store the original Salesforce ID, ensuring it remains consistent even after a restore. Below are the steps to implement this solution.
This guide covers all the necessary steps to automatically populate a custom field for both new and existing records in Salesforce. In this example we are using the Case Object.
Note: These are just examples and the solution/code can very based on your individual organization.
Overview
- Step 1: Create a new custom field
- Step 2: Create the trigger for new records
- Step 3: Test the trigger
- Step 4: Create the Batch Apex class for existing records
- Step 5: Run the Batch Apex class
- Step 6: Monitor the batch job
- Step 7: Verify the results
- Step 8: Schedule the batch job
Step 1: Create a new custom field
- Navigate to Setup > Object Manager > Object (Case).
- Click Fields & Relationships > New.
- Select Text as the data type and click Next.
- Configure Field:
- Field Label: Case ID
- Field Name: (API): CaseId__c
- Field Length: Set the length to 18 characters
- (Optionally) Select the checkbox Set this field as the unique record identifier from an external system.
- Set field-level security ensuring the field is visible to all profiles that need access and click Next.
- Add to the appropriate page layouts and click Save.
Step 2: Create the trigger for new records
Next, create a trigger to automatically populate the CaseId__c field with the Salesforce Case ID for new records.
- Click the gear icon >Developer Console.
- Click File > New > Apex Triggers.
- Enter a Name (CaptureCaseId).
- Select sObject (Case) and click submit.
- Paste the following trigger code to populate the CaseId__c field for new records:
trigger PopulateCaseIdField on Case (after insert) {
// Create a list to hold the cases to update.
List<Case> casesToUpdate = new List<Case>();
// Iterate over each Case record
for (Case caseRecord : Trigger.new) {
// Ensure the CaseId__c field is blank before updating
if (String.isBlank(caseRecord.CaseId__c)) {
// Create a new instance of the Case record to update
Case updatedCase = new Case(Id = caseRecord.Id);
updatedCase.CaseId__c = caseRecord.Id; // Set the custom field with the 18-character Case ID
casesToUpdate.add(updatedCase);
}
}
// Perform the update for all cases that need it
if (!casesToUpdate.isEmpty()) {
update casesToUpdate;
}
}
- Select Ctrl+S to save the trigger.
Step 3: Test the trigger
- Navigate to the Case Object in Salesforce and create a new case.
- After saving, verify that the ID was inserted into the Case ID field.
Step 4: Create the Batch Apex class for existing records
To update the CaseId__c field for all existing Case records, we need to create a Batch Apex class.
- In Setup, go to Apex Classes and click New.
- Paste the following code to create the batch class for updating existing records:
global class UpdateExistingCaseIds implements Database.Batchable<SObject>, Database.Stateful {
// The start method defines the query to select records
global Database.QueryLocator start(Database.BatchableContext bc) {
// Query all Case records where CaseId__c is blank
return Database.getQueryLocator([SELECT Id, CaseId__c FROM Case WHERE CaseId__c = null]);
}
// The execute method processes each batch of records
global void execute(Database.BatchableContext bc, List<Case> caseRecords) {
List<Case> casesToUpdate = new List<Case>();
// Iterate through the cases and update the CaseId__c field
for (Case caseRecord : caseRecords) {
caseRecord.CaseId__c = caseRecord.Id; // Set the custom field with the 18-character Case ID
casesToUpdate.add(caseRecord);
}
// Perform the update for all cases in this batch
if (!casesToUpdate.isEmpty()) {
update casesToUpdate;
}
}
// The finish method runs after all batches are processed
global void finish(Database.BatchableContext bc) {
System.debug('Batch job complete: CaseId__c field updated for all records.');
}
}
- Save the Class (Name populates to “UpdateExistingCaseIds”
Step 5: Run the Batch Apex class
To update the CaseId__c field for existing records, run the batch class:
- Open the Developer Console.
- Click Debug > Open Execute Anonymous Window.
- Past the following code to run the batch job:
// Execute the batch job to update existing records
UpdateExistingCaseIds batch = new UpdateExistingCaseIds();
Database.executeBatch(batch, 200); // Adjust batch size if needed
- Click Execute to start the batch job.
Step 6: Monitor the batch job
- In Setup, search for Apex Jobs.
- In the Job Monitor, you can monitor the progress of the batch job. You’ll see details about how many batches have been processed, if any errors occurred, and when the job is completed.
Step 7: Verify the results
- Go to the Cases tab and open some Case records.
- Verify that the CaseId__c field has been populated with the 18-character Case ID.
Note: Alternatively, you can run a SOQL query in the Developer Console to verify the results:
SELECT Id, CaseId__c FROM Case WHERE CaseId__c = null
Step 8: Schedule the batch job
If you’d like to schedule this batch job to run periodically (in case more records with a blank CaseId__c are added later), you can create a Scheduled Apex Class.
- Create the Scheduled Apex Class:
- Navigate to Setup > Apex Classes > New
- Paste the ScheduledUpdateCaseIds code below and save the class
global class ScheduleUpdateCaseId implements Schedulable {
global void execute(SchedulableContext sc) {
UpdateExistingCaseIds batch = new UpdateExistingCaseIds();
Database.executeBatch(batch, 200); // Adjust batch size if necessary
}
}
- Click Save.
The name defaults to: ScheduleUpdateCaseId. - In Setup, search for Apex Classes.
- Click Schedule Apex.
- Give the job a name, select the ScheduleUpdateCaseId class, and set the frequency (i.e. daily, weekly).
- Save the scheduled job.
For more details on how the External ID can be used, see: How External IDs solve Salesforce ID challenges