I'm trying to build a general-purpose piece of functionality that can be added to batch classes. My class is Batchable
itself and it will take in an instance of another Batchable
. For each of the methods in the Batchable
interface, my class will do some extra work, then delegate to the other Batchable
. In doing so, I'm having trouble...
Something that stands out as very odd about the Batchable
interface is that the docs say you must implement:
global (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext bc) {}
So the return type of the start()
method could be Database.QueryLocator
or Iterable<sObject>
. Which is not normally possible.
Most of the time, this doesn't matter, but if I have a reference to an instance of a Batchable
, it seems like I can't call the Database.QueryLocator
version. For example:
public with sharing class BatchableStartMethodTest implements Database.Batchable<SObject> {
public void execute(Database.BatchableContext bc, List<SObject> scope) {
}
public void finish(Database.BatchableContext bc) {
}
public Database.QueryLocator start(Database.BatchableContext bc) {
return null;
}
public static void doesntCompile() {
Database.Batchable<SObject> instance = new BatchableStartMethodTest();
Database.QueryLocator locator = instance.start(null);
}
public static void compiles() {
BatchableStartMethodTest instance = new BatchableStartMethodTest();
Database.QueryLocator locator = instance.start(null);
}
}
In this, the doesntCompile()
method gives a compilation error:
Error:(20, 31) Illegal assignment from System.Iterable to Database.QueryLocator (20:31)
I can see what the error is getting at, but I can't see how to tell the compiler that I'm using the QueryLocator
version. I might try to define my own derived interface, but that's not possible either:
public interface BatchableQueryLocator extends Database.Batchable<SObject> {
Database.QueryLocator start(Database.BatchableContext bc);
}
Error:(7, 18) Method return types clash: System.Iterable vs Database.QueryLocator from the type Database.Batchable (7:18)
Does this just mean that two return types in Batchable
is some weird special case in the compiler that I cannot deal with in the way I want to? I could create an interface that doesn't extend the existing Batchable
i.e.
public interface BatchableQueryLocator {
Database.QueryLocator start(Database.BatchableContext bc);
}
But that seems ugly because then I don't get full type-safety - I can't tell the compiler that my method expects something that implements both Batchable
and BatchableQueryLocator
. Any suggestions?