Gluon Digital

Offical carrier of the Strongforce

Developing Data Migrations and Integrations with Salesforce Best Practice #10: Don't Hard-code Salesforce IDs; They Change with Environments

Developing Data Migrations and Integrations with Salesforce Best Practice #10: Don't Hard-code Salesforce IDs; They Change with Environments
David Masri         Author:
David Masri
Founder & CEO

When coding data migrations or integrations with Salesforce it's not uncommon to have a need to specify specific record Ids in your code.

For example:

  1. Suppose you are given a rule that says: If the contact is an employee of our firm, it must be of record type "Employee", and its parent account must be the "XYZ Employee Holding Account".
  2. As part of a data migration you are given a set of rules on how to assign Owners to Accounts.

For these types of use cases, it's not uncommon to see developers hard-coding Ids in code. But it's a huge mistake, because they change with environments (sandboxes).

Mature organizations insist on having multiple environments (DEV, QA, UAT, Production, Production Support). Hard-coding Ids force you to have to make code changes as part of the deployment process. Even if you are (for some awful reason) willing to tolerate such a manual and error prone deployment process, once the project is done and you hand the code off to your client's support team, they will have to support it. It's unacceptable to force your client to maintain separate versions of the code for each environment, or to continue with manual deployment procedures.

You can argue that user Ids maintain the same Id across production and sandboxes, except that they only do if the user is created in production before the sandbox is refreshed. At some point you are going to manually create a user in a sandbox and they will have a different Id then production. It's not realistic to expect the sandbox to be refreshed every time a user is added.

If you spin up a developer sandbox, your holding account won't exist, and when you create it, it will have a different Id.

With a partial sandbox you may get lucky and have the needed holding accounts, but why gamble?

That leaves us with full sandboxes. Full sandboxes are expensive, it's not fair to force your client to pay for extra full sandboxes just because you hard-coded Ids. Also, a full sandbox can only be refreshed once a month, what are you going to do if you get a requirement change one week after the refresh? Waiting three weeks to write\fix your code is probably not an option.

Not hard-coding Ids has been long established as a Salesforce developer best practice* for all Salesforce code, be it Apex code, Workflows, Process Builders or validation rules. Integration and migration developer should be following this best practice too.

Store those Ids in configuration files or cross-reference tables, personally I like to store the cross-reference tables directly in Salesforce as external Ids on the referenced record. So, for the Account example I create, and external Id field on the account object and set the value to "EMPL_HOLD_ACCNT". For the owner example I do the same but have a unique value for each user. For record types I use the DeveloperName field as an external Id. We can then download the cross-reference tables to be used as part of our migration or integration code at any time (or use Upsert if the object/field supports it). It's Ok to hardcode the external Ids because those do NOT change between environments.
Don't Hard-code Salesforce IDs; They Change with Environments.

*If you google "Hard code IDs" you get a bunch of Salesforce articles!

This article is adapted from my book: Developing Data Migrations and Integrations with Salesforce.