0

For person accounts, when i am trying to change their record type to business account record type, it is not allowing me to do so using Apex.Below is the code snippet I am trying(for testing purpose for a person account record in sandbox using dev console):

     List<Account> lstAcnts = [select id,recordtypeid from account where id ='001p000000CWhcq'];
        List<Account> lstUpd = new List<Account>();


        for(Account obj:lstAcnts)
        {


        obj.recordtypeid = '01290000000h8gl';// Business account record type id
        lstUpd.add(obj);
      }

update lstUpd;

Below is the error I get :

Line: 16, Column: 1 System.DmlException: Update failed. First exception on row 0 with id 001p000000CWhcqAAD; first error: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, invalid record type: []

What should I do to change the record type of person account record to a business account record type ?

1
  • 1
    Remember that a Person Account consists of an Account and a Contact record, rather than trying to change the person account to Account I think creating a new Account and Contact record would be work, but would need any records that are linked to the Person Account would need to be linked to the new Account record.
    – Dave Humm
    Aug 31, 2016 at 13:10

2 Answers 2

1

You shouldn't use record type Ids like these as there is no guarantee that the IDs will be the same across environments. If this works in Sandbox it might not in Production. Instead you should query based on Record Type Developer Name.

There is a really good post and utility posted here: What would be the best approach to get the recordtype id

2
  • I already mentioned that its just a code snippet for testing purpose(not the actual code).The issue is something else.The record types are completely valid on sandbox and correct ids are used in the code snippet
    – Abhijeet
    Aug 31, 2016 at 13:15
  • 1
    @Abhijeet Usually you do get this error when you're using an Id that doesn't exist in the database.
    – Adrian Larson
    Aug 31, 2016 at 13:41
1

This issue highlights why you should NEVER use hard-coded ids in your Apex. Salesforce itself recommends you avoid it. Their example should be illustrative for you here.

Best Practice: Avoid Hardcoding IDs

Short Description of Advice

Don't hardcode IDs into queries or code. Rather query on some other data to retrieve the desired rows.

Motivation for Advice

Record IDs can change - for example between a sandbox and a production environment. If code is not written properly, this will result in faulty code. Explanation

When deploying Apex code between Sandbox and Production environments, or installing Force.com AppExchange packages, it is essential to avoid hardcoding IDs in the Apex code. By doing so, if the record IDs change between environments, the logic can dynamically identify the proper data to operate against and not fail. Here is a sample that hardcodes the record type IDs that are used in an conditional statement. This will work fine in a specific environment that the code is developed in, but if this code were to be installed in a separate org (ie. as part of an AppExchange package), there is no guarantee that the record type identifiers will be the same.

for(Account a: Trigger.new){

   //Error - hardcoded the record type id
   if(a.RecordTypeId=='012500000009WAr'){             
      //do some logic here.....
   }else if(a.RecordTypeId=='0123000000095Km'){
      //do some logic here for a different record type...
   }

}

Now, to properly handle the dynamic nature of the record type IDs, the following example queries for the record types in the code, stores the dataset in a Map collection for easy retrieval, and ultimately avoids any hardcoding.

//Query for the Account record types
 List<RecordType> rtypes = [Select Name, Id From RecordType 
              where sObjectType='Account' and isActive=true];

 //Create a map between the Record Type Name and Id for easy retrieval
 Map<String,String> accountRecordTypes = new Map<String,String>{};
 for(RecordType rt: rtypes)
    accountRecordTypes.put(rt.Name,rt.Id);

  for(Account a: Trigger.new){

    //Use the Map collection to dynamically retrieve the Record Type Id
    //Avoid hardcoding Ids in the Apex code
    if(a.RecordTypeId==accountRecordTypes.get('Healthcare')){             
       //do some logic here.....
    }else if(a.RecordTypeId==accountRecordTypes.get('High Tech')){
       //do some logic here for a different record type...
    }

 }

By ensuring no IDs are stored in the Apex code, you are making the code much more dynamic and flexible - and ensuring that it can be deployed safely to different environments.

2
  • thanks for this but i am already aware of this fact.Unfortunately, my question is related to some other thing and this does not address it.Above is just a code snippet i tried for testing purpose(its not the actual code). Any advice on my issues?
    – Abhijeet
    Aug 31, 2016 at 13:13
  • 1
    You need to query for the business account RecordTypeId... Your code would be nearly verbatim except if you're not inclined to map them you can just query for the one record you want by DeveloperName.
    – Adrian Larson
    Aug 31, 2016 at 13:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .