7

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.

1 Answer 1

10

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 batch

From the Apex doc:

Starting with Apex saved using Salesforce.com API version 26.0, you can call Database.executeBatch or System.scheduleBatch from the finish method. This enables you to start or schedule a new batch job when the current batch job finishes. For previous versions, you can’t call Database.executeBatch or System.scheduleBatch from any batch Apex method. Note that the version used is the version of the running batch class that starts or schedules another batch job. If the finish method in the running batch class calls a method in a helper class to start the batch job, the Salesforce.com API version of the helper class doesn’t matter.

1
  • crop1645 - thanks for that. Changing my code and testing out your suggestion in my org. Will update. Oct 20, 2014 at 18:40

You must log in to answer this question.

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