0

I have a List filled with n numbers of different object records. I want to pass this list to execute the method of the batch class and update the records.

for eg: there are 3 objects object A, B, C are added into one list (sObject) I need to cast into each object dynamically and then do the update.

0

You can just update your list of sObjects, SF is capable of doing it. Just make sure that the elements in your collection are sorted per object type and not chaotic. Chunking will only allow you to have up to 10 chunks for the DML, and each chunk is up to 200 records of the same object type.

So, for example, if you have 201 Accounts, 50 Leads and 399 Contacts in your list, you will use 5 chunks out of allowed 10. This will only be true if the list is sorted/ordered by object type. So if you would have a list like [Account, Lead, Contact, Account, Lead, Contact, Account, Contact, Account, Lead, Contact, Lead, Contact, Account, Lead], then update on your list will fail because the first 10 records will use all 10 of the allowed chunks.

  • 1
    As for how you'd get that list sorted, it should just be as simple as using the standard sort() method of the List type. – Derek F Dec 11 '19 at 12:17
0

If what you want is to access SObjects that are part of a List<SObject> you can probably use a factory or the switch statement

Before that you need to get SObjects names by doing something like this:

List<SObject> objects = new List<SObject>();
Account account = new Account(Name = 'AccountSObject');
Contact contact = new Contact(LastName = 'ContactSObject');

objects.add(account);
objects.add(contact);
System.debug(objects.size());

List<SObject> sObjectAccounts = new List<SObject>();
List<SObject> sObjectContacts = new List<SObject>();

List<Account> castedAccounts = new List<Account>();
List<Account> castedContacts = new List<Account>();


for(SObject sObjectTypes : objects) {
    String sObjName = sObjectTypes.getSObjectType().getDescribe().getName();
    System.debug(sObjName);
    if(sObjName == 'Account') {
        sObjectAccounts.add(sObjectTypes);
    } else if(sObjName == 'Contact') {
        sObjectContacts.add(sObjectTypes);
    }
}

System.debug('SObject Accounts: ' + sObjectAccounts.size());

for(Account a : (List<Account>) sObjectAccounts) {
    castedAccounts.add(a);
}

System.debug('Casted accounts: ' + castedAccounts.size());

Output:

enter image description here

Notice that the SObjects are not inserted to the database yet but you still get the running SObject name which you can use latter on different processes.

As how or what you want to do with these SObjects on a Database.Batchable is really up to you.

I haven't test this but here is an example for you to play around:

global class DynamicSObjectsBatchableOperations implements Database.Batchable<SObject> {

private List<SObject> objTypes;
private List<SObject> sObjectAccounts = new List<SObject>();
private List<SObject> sObjectContacts = new List<SObject>();
private List<Account> castedAccounts = new List<Account>();
private List<Account> castedContacts = new List<Account>();

// We can use the constructor to pass our list of SObjects
public DynamicSObjectsBatchableOperations(List<SObject> objList){
    objTypes = objList;   
 }

global Database.QueryLocator start(Database.BatchableContext BC) {
    String query;

    for(SObject sObjectTypes : objTypes) {
        String sObjName = sObjectTypes.getSObjectType().getDescribe().getName();

           if(sObjName == 'Account') {
            sObjectAccounts.add(sObjectTypes);

           } else if(sObjName == 'Contact') {
            sObjectContacts.add(sObjectTypes);
        }
     }

    for(Account a : (List<Account>) sObjectAccounts) {
        castedAccounts.add(a);
    }

    for(Contact c : (List<Contact>) sObjectContacts) {
        castedContacts.add(c);
    }

    if (!castedAccounts.isEmpty()) {

        query = 'SELECT Id, Name ' + 
                'FROM Account ' +
                'WHERE Id IN: castedAccounts';

        return Database.getQueryLocator(query);

    } else if (!castedContacts.isEmpty()) {

        query = 'SELECT Id, LastName ' + 
                'FROM Contact ' +
                'WHERE Id IN: castedContacts';

        return Database.getQueryLocator(query);

    } else {

        return Database.getQueryLocator(query);

    }

}

global void execute(Database.BatchableContext BC, List<SObject> objList) {

  List<SObject> accountsToupdate = new List<SObject>();
  List<SObject> contactsToupdate = new List<SObject>();


    for(SObject sObjectTypes : objList) {
        String sObjName = sObjectTypes.getSObjectType().getDescribe().getName();

           if(sObjName == 'Account') {
            accountsToupdate.add(sObjectTypes);

           } else if(sObjName == 'Contact') {
            contactsToupdate.add(sObjectTypes);
        }
     }

     if(!accountsToupdate.isEmpty()) {
        for(Object a : accountsToupdate) {
            Account acc = (Account) a;

            if (acc.Name != 'FromBatch') {
                acc.Name = 'FromBatch';
            }
        }

        Database.update(accountsToupdate, false);

       } else if (!contanctsToUpdate.isEmpty()) {
         for(Object c : contanctsToUpdate) {
            Contact con = (Contact) c;

            if (c.LastName != 'FromBatch') {
                c.LastName = 'FromBatch';
            }
        }

        Database.update(contactsToupdate, false);

     }    
  }

  global void finish(Database.BatchableContext BC) {}

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.