Salesforce: Instantiating an SObject Dynamically at Run-time

I’m sure a lot of you have this documented somewhere but I’ve recently discovered that it’s quite difficult to find an obvious reference to this knowledge on the interwobbles. So how would you create a Generic SObject at run-time? It’s rather easy thankfully:

String sObjectName = 'MyObject__c';
Schema.SObjectType t = Schema.getGlobalDescribe().get(sObjectName);
SObject s = t.newSObject();

If you require this type of functionality quite often I’d suggest putting it in a utility class.

13 thoughts on “Salesforce: Instantiating an SObject Dynamically at Run-time”

  1. Interesting post, Wes. What would be a possible use case for this? When you call Schema.getGlobalDescribe().get(SObjectName), what is returned since that object hasn’t been created yet?

    ~ Clint

    Reply
  2. Pity you are then dead in the water when you want to do a bulk upsert as AFAIK there is no way to instantiate the correctly typed list that is required starting from the object type name…

    Reply
      • Yes; if you are creating many objects of one SObject type you want to insert a list of them rather than insert them one by one. And there is no support for something like:

        List myList = List.newInstanceForType(‘Account’);
        // Create multiple SObjects here
        insert myList;

        Reply
      • No its me thats wrong as this test works:

        @isTest
        static void test() {

        Contact c = new Contact(LastName =’abc’);
        Account a = new Account(Name = ‘def’);

        List l = new List{c, a};
        insert l;
        System.assertEquals(1, [select Count() from Contact where Name = ‘abc’]);
        System.assertEquals(1, [select Count() from Account where Name = ‘def’]);
        System.assertEquals(0, [select Count() from Contact where Name = ‘123’]);
        System.assertEquals(0, [select Count() from Account where Name = ‘456’]);

        c.LastName = ‘123’;
        a.Name = ‘456’;
        update l;
        System.assertEquals(0, [select Count() from Contact where Name = ‘abc’]);
        System.assertEquals(0, [select Count() from Account where Name = ‘def’]);
        System.assertEquals(1, [select Count() from Contact where Name = ‘123’]);
        System.assertEquals(1, [select Count() from Account where Name = ‘456’]);

        try {
        upsert l;
        } catch (Exception e) {
        System.assertEquals(‘DML on generic List only allowed for insert, update or delete’, e.getMessage());
        }
        }

        Not sure where I picked up m wrong understanding of this. Thanks for taking the time to comment

        Reply
      • When converting some code to use List<SObject> instead of e.g. List<Contact> for an insert I had to change the API version from 18.0 to 20.0 for it to work at runtime. So it appears the generic list support is a recent improvement in the API.

        Reply
  3. When i try to update the sobject dynamically it throws me a error saying “System.SObjectException: Field Id is not editable”. Can you please help on this:

    Schema.SObjectType t = Schema.getGlobalDescribe().get(‘Account’);
    SObject sObjectAccount = t.newSObject();
    sObjectAccount.put(‘Id’, ‘001G000000pyDGL’);
    sObjectAccount.put(‘Name’, ‘Test’);

    Update sObjectAccount;

    Reply

Leave a Comment