0

We are doing full org deployment, we need to update the record owner to system admin for all the objects records. So initially we created batch apex to implement this for accounts object. But we have around 400 objects and it is very difficult to run the batch class for each object. So we are thinking of using custom settings in order to run this batch class for all objects.

Could it be possible to create a custom settings and add all the 400 objects and process the custom settings in the batch class? If yes, could you please help us how to implement.

Below is the batch class for one object (account):

global class AccountOwnerUpdate implements Database.Batchable<sObject> 
{
    global Set<Id> userIds = new Set<Id>();

    global AccountOwnerUpdate(){
        List<String> userEmailList =new List<String>{'test1@test.com.invalid','test2@test.com.invalid'};
        List<String> userNameList =new List<String>{'test2@test.com.sb13','test3@test.com.sb13'};
            for(User objUser: [Select id from User Where (Email IN: userEmailList OR UserName IN:userNameList) ]){
                userIds.add(objUser.id);
            }
    }
    global Database.QueryLocator  start(Database.BatchableContext bc) {
        //String recId = '0014000000PcRkmAAF';
        //String query ='Select id,OwnerId,LastModifiedDate from Account Where ID =:recId '; // change object name
        String query ='Select id,OwnerId,LastModifiedDate from Account'; // change object name
        //String query ='Select id,OwnerId from Account Limit 1 ';
        return Database.getQueryLocator(query);
    }
    global void execute(Database.BatchableContext bc, List<Account> records){
        User objUser = [Select id,email from User Where email ='test1@test.com' limit 1];


        system.debug('objUser=='+objUser);
        for(Account acc: records){//change object name 
            system.debug('acc.ownerId==='+acc.ownerId);
            if(!userIds.contains(acc.ownerId)){
                acc.ownerId = objUser.id;
                //acc.LastModifiedDate = acc.LastModifiedDate; 
            }

        }
        system.debug('records=='+records);
        update records;
    }    
    global void finish(Database.BatchableContext bc){
        // execute any post-processing operations
    }    
}
  • 2
    Yes, you could achieve this using Custom Settings, or better Custom Metadata, with Dynamic SOQL. Where are you stuck? Why don't you give the implementation a try and come get assistance from SFSE when you encounter issues? – David Reed Dec 20 '19 at 13:50
3

I have done this before, and not sure you actually need to store the list anywhere - you could just add the list of objects to the batch when you create it as a variable. Any variable you set when you invoke the batch are always available during the lifetime of the batch (though you need stateful if you want to track on-going counts)

So build the list, remove the last item and query for that, and add the remaining list to the batch so you can chain the batches.

Then in the finish, invoke a new batch with the last element of the list that you set at the start as the new object to query and then set the remainder of the list on the new batch, and it will keep going until there are no objects in the list to query

You can also just set the user id as a variable and pass that along the chain - no need to keep querying.

  • +1 - I have done similar (batch chaining with ever dwindling collection of objects in constructor) to do a multi-pass through many objects for data purging – cropredy Dec 21 '19 at 6:09

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.