function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
WarjieWarjie 

Iterable Batch Class

Hi All, I've created a batch class implementing Iterable. A class calls the batch class passing the list of records to be inserted (in the batch). I was able to save this code without issue but I'm not sure if this will work. Can you give me your insights on this please?

Class that calls the batch:
//these lists are filled inside the class and are to be inserted inside the batch to prevent DML 10001
batchWOSharing bc = new batchWOSharing(jobShareList, 'Jobs__Share');
ID batchProcessId = Database.executeBatch(bc, 200);
batchWOSharing bc2 = new batchWOSharing(opportunityShareList, 'OpportunityShare');
ID batchProcessId2 = Database.executeBatch(bc2, 200);    
batchWOSharing bc3 = new batchWOSharing(invoiceShareList, 'Invoice__Share');
ID batchProcessId3 = Database.executeBatch(bc3, 200);
batchWOSharing bc4 = new batchWOSharing(accShare, 'AccountShare');
ID batchProcessId4 = Database.executeBatch(bc4, 200);

Batch class called:
global class batchWOSharing implements Database.Batchable<sObject>{
    public List<sObject> objectList = new List<sObject>();
    String obj;
	
    global batchWOSharing(List<sObject> objectList2, String obj2){
		this.obj = obj2;        
        this.objectList = objectList2;
    }
	
	global Iterable<sObject> start(Database.batchableContext BC){
		return new List<sObject>();
	}	
    
    global void execute(Database.BatchableContext BC, List<sObject> scope){   
		List<sObject> objectToUpdate = new List<sObject>();

        for(sObject s: scope){
            objectToUpdate.add(s);
        }
		if(obj == 'Jobs__Share'){
			List<Jobs__Share> jobShareList = (List<Jobs__Share>) objectToUpdate;
			Database.insert(objectToUpdate, false);
		}
		if(obj == 'OpportunityShare'){
			List<OpportunityShare> opptyShareList = (List<OpportunityShare>) objectToUpdate;
			Database.insert(objectToUpdate, false);
		}
		if(obj == 'Invoice__Share'){
			List<Invoice__Share> invShareList = (List<Invoice__Share>) objectToUpdate;
			Database.insert(objectToUpdate, false);
		}
		if(obj == 'AccountShare'){
			List<AccountShare> accShareList = (List<AccountShare>) objectToUpdate;
			Database.insert(objectToUpdate, false);
		}
    }
    
    global void finish(Database.BatchableContext BC){
    }
}

 
James LoghryJames Loghry

I don't think it will work.  The start method is used to return the list of records the batch process runs on, so at the very least, you will need to return "this.objectList" instead of an empty array of sobjects.

Also, unless I am missing something, it looks like your execute method could be reduced to the following:

global void execute(Database.BatchableContext BC, List<sObject> scope){  
    insert scope;
}
 

 

WarjieWarjie
Thanks James,

Yes I should change the return to 'return this.objectList'

The reason why I do some typecasting is for the system to know in which object should the records be inserted.

BTW, I'm thinking if I could consolidate first the objects to 1 sObject and call the batch once (instead of 4). However, I don't know how will it distinguish (in the batch) which object should the records be inserted. Below's the code change:
 
List<sObject> finalObjectList = new List<sObject>();
                for(Jobs__Share jo: jobShareList){
                    finalObjectList.add((sObject) jo);
                }
                for(Jobs__Share oo: opportunityShareList){
                    finalObjectList.add((sObject) oo);
                }
                for(Jobs__Share io: invoiceShareList){
                    finalObjectList.add((sObject) io);
                }
                for(Jobs__Share ao: accShare){
                    finalObjectList.add((sObject) ao);
                }
                batchWOSharing bc4 = new batchWOSharing(finalObjectList); 
                ID batchProcessId4 = Database.executeBatch(bc4, 200);