13

I don't think what I am trying to do can be done with my current setup, but before I embark on some rework, I just wanted to check I haven't missed an approach...

I have a scheduled class that executes a batch. So far so good. But to run that batch, I need to check a date from an external web service to include in the SOQL - and this is where I am running into a problem. A scheduled class can only make a callout if the callout is run in an @future context. But sadly, a class running as @future can't then execute a batch, or even schedule a batch to run in the future using system.schedulebatch. So is there any approach that would let me schedule a class to make a callout, and then also execute/schedule a batch that I am missing? Right now, I am thinking I need my scheduled class to make the callout via @future and have the @future update a custom setting with the results, and have the scheduled class also schedule a class to execute my batches run in x mins to allow time for @future to run?

12

Why not just perform the callout in your Batch Apex start method? This means you will always start the Batch Apex job from your Scheduled apex job, but i think is on balance better than having to marshall schedule jobs between @future jobs?

public with sharing class BatchWithCallout 
   implements Database.Batchable<SObject>, Database.AllowsCallouts 
{
    public Database.QueryLocator start(Database.BatchableContext BC) 
    { 
        // Callout for Date
        HttpRequest request = new HttpRequest();
        request.setEndpoint('http://www.timeapi.org/pdt/next+monday');
        request.setMethod('GET');
        Http http = new Http();
        HttpResponse response = http.send(request);
        String dateValue = response.getBody();
        List<String> dateParts = dateValue.split('T');

        // Query with date returned
        return Database.getQueryLocator(
              'select Id from Opportunity where CloseDate < ' + dateParts[0]); 
    }

    public void execute(Database.BatchableContext info, List<SObject> opportunities) {}

    public void finish(Database.BatchableContext info) { }
}
  • 1
    Ah - of course - yes, that worked nicely. I always define by queries outside the batch - so forgetting you can actually do that in the start method. Thanks once again, and merry christmas! – BritishBoyinDC Dec 23 '13 at 23:37
  • Most welcome, Merry Christmas to you as well! :) – Andrew Fawcett Dec 23 '13 at 23:47
  • And don't overlook the "Database.AllowsCallouts" part in the class declaration. It's essential. The interface does not require you to implement any extra methods. – Sander de Jong Aug 23 '16 at 9:00

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.