0

I am working on a batch class and in my start method I have a "Set" of contact Ids. I want to use this Set in the execute method of the batch job, but I am getting some errors shown below. How would I modify my code to resolve this error.

I tried modifying the Database.Batchable to Database.Batchable, but that did not work.

global class CustomerBatch implements Database.Batchable<SObject>, Database.Stateful, Database.AllowCallouts {

  global Set<Id> start(Database.BatchableContext BC) {
   Set<Id> customerIds = new Set<Id>();
   Contact[] contacts = [SELECT Id FROM Contact WHERE customer_overdue__c = TRUE];
   for( Contact c : contacts ) {
    customerIds.add(c.Id);
  } 
  if( customerIds.size() > 0) {
   return customerIds;
  }
  return null;
 }

 global void execute(Database.BatchableContext BC, Set<Id> customerIdList) {
  System.debug('Customer Id List ---> ' + customerIdList);
 }

 global void finish(Database.BatchableContext BC) {
 }

} // end batch class

The errors I am getting are these:

Class CustomerBatch must implement the method: System.Iterable Database.Batchable.start(Database.BatchableContext)

Class CustomerBatch must implement the method: void Database.Batchable.execute(Database.BatchableContext, List)

2 Answers 2

8

Sets are not iterable in Apex. You can use a Set to accumulate a unique collection of Ids, and then convert to a List<Id>, which is iterable:

global class CustomerBatch implements Database.Batchable<Id>, Database.Stateful, Database.AllowsCallouts {

  global Iterable<Id> start(Database.BatchableContext BC) {
   Set<Id> customerIds = new Set<Id>();
   Contact[] contacts = [SELECT Id FROM Contact WHERE customer_overdue__c = TRUE];
   for( Contact c : contacts ) {
    customerIds.add(c.Id);
  } 
  if( customerIds.size() > 0) {
   return new List<Id>(customerIds);
  }
  return null;
 }

Note that you also must change the signature of execute() to match the interface:

global void execute(Database.BatchableContext BC, List<Id> customerIdList) {

It is most likely a better strategy, though, just to query Contacts in your start() method instead of working with iterators. Let Salesforce deal with acquiring and managing the complete scope of the batch job.

Your execute() method can re-query records to acquire related data or whatever you require. Note also that unless you are building a managed package, there is no need to use global; your class should be public.

public class TestQ318103 implements Database.Batchable<sObject>, Database.Stateful, Database.AllowsCallouts {
  public Database.QueryLocator start(Database.BatchableContext bc) {
    return Database.getQueryLocator([SELECT Id FROM Contact WHERE customer_overdue__c = TRUE]);
  }

 public void execute(Database.BatchableContext bc, List<Contact> scope) {
  System.debug('Customer Id List ---> ' + scope);
 }

 public void finish(Database.BatchableContext bc) {
 }
}
0

The start method has a defined signature that cannot be altered. What you are looking for is a parameterized constructor

global class CustomerBatch implements Database.Batchable<SObject>, Database.Stateful, Database.AllowCallouts {

Set<ID> ids;
public CustomerBatch(Set<Id> ids){
 this.ids = ids;
}

You can use the set in you start or execute method. Aee more here https://www.infallibletechie.com/2018/06/passing-parameter-to-batch-apex-in.html?m=1

2
  • In my start method, I make an api call to get the Ids from an external system. I then want to use these Ids to query the Contact object. I understand the constructor can accept an argument but I am trying to return a "Set" in the start method. Is this not possible? It allows me to return a List for some reason, but not a set? Aug 28, 2020 at 4:14
  • The start method can either return a list of iterable type or a query locator. That the contract specified by batchable. You can always return a list and convert it to a set but even if you return a list the only difference you will get is it will order but you won't be able to use set methods on it
    – manjit5190
    Aug 28, 2020 at 7:37

You must log in to answer this question.

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