0

So I trying to use list of wrapper class as iterator in batch. below is the code I have tried so far

Iterable class

public class AccountCustomIterator implements  Iterable<AccountWrapper>, Iterator<AccountWrapper>
{
    public List<AccountWrapper> lstAccountWrapper;
    Integer i {get; set;} 

    public AccountCustomIterator(List<AccountWrapper> lstAccountWrapper)
    { 
        this.lstAccountWrapper = lstAccountWrapper;
        i = 0; 
    }  
    public Boolean hasNext() 
    { 
        return (i >= lstAccountWrapper.size()) ? false : true; 
    } 

    public AccountWrapper next()
    { 
        if(i  < lstAccountWrapper.size())
        {
            i = i+1;
            return lstAccountWrapper[i-1]; 
        }
        return null;
    } 
    public Iterator<AccountWrapper> iterator() 
    { 
        return this; 
    } 
    public class AccountWrapper
    {
        public String strUnique = '';
        public List<Account> lstAccount = new List<Account>();
        public AccountWrapper(String strUnique, List<Account> lstAccount)
        {
            this.strUnique = strUnique;
            this.lstAccount = lstAccount;
        }
    }
}

And here is the batch class

global class AccountChildrecordsUpdateBatch implements Database.batchable<AccountCustomIterator.AccountWrapper>
{
    global Iterator<AccountCustomIterator.AccountWrapper> start(Database.BatchableContext BC)
    {
        List<AccountCustomIterator.AccountWrapper> lst = new List<AccountCustomIterator.AccountWrapper>();
        return new AccountCustomIterator(lst);
    }

    global void execute(Database.BatchableContext BC, List<AccountCustomIterator.AccountWrapper> scope)
    {

    }      


    global void finish(Database.BatchableContext BC)
    {

    }
}

unable to save the batch file getting below error

line 1, col 14. Class AccountChildrecordsUpdateBatch must implement the method: System.Iterable Database.Batchable.start(Database.BatchableContext)

2 Answers 2

4

Note that there are two separate classes: Iterable and Iterator. In your question you use the latter where the interface demands the former.

Note also that a List is an Iterable:

Object demo = new List<String>();
system.assert(demo instanceof Iterable<String>);

So you can just return the list. No need to define your own custom classes nor wrap the list in anything.

public with sharing class MyBatch implements Database.Batchable<MyClass>
{
    public Iterable<MyClass> start(Database.BatchableContext context)
    {
        return new List<MyClass>();
        // obviously the list can be populated
        // the point here is just to illustrate
        // you can return a List as an Iterable
    }
    public void execute(Database.BatchableContext context, List<MyClass> scope) { }
    public void finish(Database.BatchableContext context) { }
}
1
  • yep exactly. I also noticed that in start method we can't pass the List<MyClass> scope . I had to provide the List<object> scope
    – Ratan Paul
    Commented Oct 23, 2017 at 16:59
0

ok So I found the issue able to resolve it. Below is code for custom data type as batch iterator

global class AccountChildrecordsUpdateBatch implements Database.batchable<AccountCustomIterator.AccountWrapper>
{
    global Iterable<AccountCustomIterator.AccountWrapper> start(Database.BatchableContext BC)
    {
        List<AccountCustomIterator.AccountWrapper> lstAccWrap = new List<AccountCustomIterator.AccountWrapper>();

        List<Account> lstAccount = [SELECT Id, Name FROM Account];                   
        map<String, List<Account>> mapUniqNameToLstAcc = new map<String, List<Account>>();
        for(Account objAcc: lstAccount)
        {
            if(!mapUniqNameToLstAcc.containsKey(objAcc.Name))
                mapUniqNameToLstAcc.put(objAcc.Name)), new List<Account>{});
            mapUniqNameToLstAcc.get(objAcc.Name)).add(objAcc);
        }

        for(String strUnique:mapUniqNameToLstAcc.keySet())
        {
            lstAccWrap.add(new AccountCustomIterator.AccountWrapper(strUnique, mapUniqNameToLstAcc.get(strUnique)));
        }
        return new AccountCustomIterator(lstAccWrap);
    }

    global void execute(Database.BatchableContext BC, List<object> scope)
    {
        List<AccountCustomIterator.AccountWrapper> lstWrap = (List<AccountCustomIterator.AccountWrapper>)scope;
        system.debug('======exetcute method-scope--'+ lstWrap);
    }      


    global void finish(Database.BatchableContext BC)
    {

    }
}

You must log in to answer this question.

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