You need to sign in to do that
Don't have an account?
Ken Koellner
Getting Iterator to work with Batchable
I'm trying to write a Batchable that uses an Iterable. I'm getting one error. The example in the documentation isn't much help as it declares the Iterable without a type and I can't even get that to compile.
The issue in in the assignment of myIter in the start() method. I get a runtime exception on that line.
global class KenTestBatch implements Database.batchable<Transaction__c> { /* KenTestBatch batcher = new KenTestBatch(); Id procId = Database.executeBatch(batcher,1); System.debug('ProcId ' + procId); */ global Iterable<Transaction__c> start(Database.BatchableContext info){ Iterable<Transaction__c>myIter=(Iterable<Transaction__c>)new KenTestCustomIterable(); return myIter; } global void execute(Database.BatchableContext info, List<Transaction__c> scope){ for (Transaction__c tran : scope) { // Do processing here. } } global void finish(Database.BatchableContext info){ } } global class KenTestCustomIterable implements Iterator<Transaction__c>{ List<Transaction__c> tranList {get; set;} Integer i {get; set;} public KenTestCustomIterable() { tranList = [SELECT Id, Back_Office_Order__c FROM Transaction__c limit 100]; i = 0; } global boolean hasNext(){ if(i >= tranList.size()) { return false; } else { return true; } } global Transaction__c next(){ i++; return tranList[i-1]; } }
Ken, I looked at a similar set of code I wrote to do batchable on a CSV file and I saw that I did this; Hopefully this can help. It is part of a much larger set of code so it won't compile directly for you but you can see how I broke the problem down into bits
Hi Ken,
Update start method of batch class As :
global Iterable<Transaction__c> start(Database.BatchableContext info) {
Return new KenTestCustomIterable();
}
Let me know if still facing the issue.
mark it as solved if the solution worked as it might help others..!!
Thanks,
Prashant Tiwari
PT,
That won't compile, I get-- : Return value must be of type: Iterable<SOBJECT:Transaction__c>
One solution that does work is to add another class that wraps the custom iteratable. (In the manual, the analogous class is called "foo"; a metasyntacic symbol normally used for inconsequential variables.)
See the KenTestIterableWrapper class now included in my example. I'm not sure if there is a way to simplify it by making the functionality of the Wrapper class a method inside the KenTestCustomerIterator class. But in any case, the example below now compiles and executes.
I have following 2 classes and third class is throwing the error; can anyone identify; why it is throwing the error :-
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
global class OppHistMonthlyUpload_Iterator implements Iterator<Opportunity_Trend_History__c>{
List<Opportunity_Trend_History__c> oppTrendHistList {get; set;}
Integer i {get; set;}
public OppHistMonthlyUpload_Iterator(List<Opportunity_Trend_History__c> othlist){
if(oppTrendHistList == null){
oppTrendHistList=new List<Opportunity_Trend_History__c>();
}
oppTrendHistList.addAll(othlist);
i = 0;
}
global boolean hasNext(){
if(i >= oppTrendHistList.size()) {
return false;
} else {
return true;
}
}
global Opportunity_Trend_History__c next(){
i++;
return oppTrendHistList[i-1];
}
}
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
global class OppHistMonthlyUpload_Iterable implements iterable<Opportunity_Trend_History__c>{
List<Opportunity_Trend_History__c> oppTrendHistList = new List<Opportunity_Trend_History__c>();
public OppHistMonthlyUpload_Iterable(List<Opportunity_Trend_History__c> othlist){
this.oppTrendHistList.addAll(othlist);
}
global Iterator<Opportunity_Trend_History__c> Iterator(){
return new OppHistMonthlyUpload_Iterator(oppTrendHistList);
}
}
***********************************************************************************************************************************************************************
Error: Compile Error: Class DMLInsertForMoreThan10000Rows_BATCH must implement the method: System.Iterable<SObject> Database.Batchable<SObject>.start(Database.BatchableContext)
***********************************************************************************************************************************************************************
global class DMLInsertForMoreThan10000Rows_BATCH implements
Database.Batchable<sObject>, Database.Stateful {
global Map<Id, Opportunity_Trend_History__c> mapOfOppIdNOppTrendHist = new Map<Id, Opportunity_Trend_History__c>();
global DMLInsertForMoreThan10000Rows_BATCH(Map<Id, Opportunity_Trend_History__c> mapOfOppIdNOppTrendHist){
mapOfOppIdNOppTrendHist.putAll(mapOfOppIdNOppTrendHist);
}
global Iterable<Opportunity_Trend_History__c> start(Database.BatchableContext bc) {
OppHistMonthlyUpload_Iterable abc = new OppHistMonthlyUpload_Iterable(mapOfOppIdNOppTrendHist.values());
return abc;
}
global void execute(Database.BatchableContext bc, List<Opportunity_Trend_History__c> scope)
{
insert scope;
}
global void finish(Database.BatchableContext bc){
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setTargetObjectId(UserInfo.getUserId());
mail.setSaveAsActivity(false);
mail.setSenderDisplayName('Batch Processing');
mail.setSubject('Batch Process Completed');
mail.setPlainTextBody('Batch Process has completed');
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
}