I am attempting to call a batch within a batch. The reason why I am attempting this is because the values returned in the main batch is used in a query to grab other records to be updated from a different object. The sample code below might do a better job of explaining this :
global void execute(Database.BatchableContext BC, List<sObject> scope){
System.Debug('====> In AccountAssignmentBatch2');
List<Zip_Code__c> zipList = new List<Zip_Code__c>();
List<Account> accountsToUpdate = new List<Account>();
Set<String> zipSet = new Set<String>();
// loop through the zipcode records
for (sObject s : scope) {
// cast the sObject to zip code
Zip_Code__c zip = (Zip_Code__c)s;
zipSet.add(zip.zip_code__c);
// update the zip code record to show it was processed
zip.update_required__c = false;
zipList.add(zip);
System.debug('====> In AccountAssignmentBatch2: Processing Zip ' + zip.Zip_Code__c);
}
database.executeBatch(new AccountAssignmentBatchHelper('select id, Assignment_Error__c from account where zip5__c in :zipSet'));
/*List<Account> accountsList = new List<Account>([select id, Assignment_Error__c from account where zip5__c in :zipSet]);
for (Account a : accountsList) {
a.Assignment_Error__c = null;
accountsToUpdate.add(a);
}
// trigger an update on the accounts.
System.Debug('====> Size of accounts to update is : ' +accountsToUpdate.size() );
if (accountsToUpdate.size() > 0) update accountsToUpdate;*/
System.Debug('====> Size of zips to update is : '+zipList.size());
// update zip code records
if (zipList.size() > 0) update zipList;
}
The lines of code commented out were originally part of this main code but I moved them into the new batch class which I call the AccountAssignmentBatchHelper because I was encountering governor limits issue with the number of soql calls being made. This saves without issues but when I run my test class I encounter the error : System.AsyncException: Database.executeBatch cannot be called from a batch start, batch execute, or future method.
Can someone explain why this is happening and how I may be able to resolve this? Thanks for any input on this.
Best Answer
You can chain batches only through the finish() method. The reason for this is that the execute() method will be called many times for a given batch start() and this can get out of hand with too many batches scheduled.
Have your batchable class implement
Database.stateful
and save any information you need as class member variables, available to the finish() method for starting the next batchFrom the Apex doc: