+ Start a Discussion
tomstertomster 

Batch class "execute" not running on 1st scope iteration for large data

Hello,

Has anyone ever experienced this? When running a batch class, the query fetches 9200 rows (sometimes over 10000 so this is why I'm using batch). I then proceed to loop and insert in a custom object. But everytime the insert is missing 200 rows (size of scope) so 9000 rows are inserted instead of 9200. If I put the scope to 500, then 500 rows are missing. When I debug, I notice that the first SerialBatchApexRangeChunkHandler is always empty as if the execute doesn't happen until the 2nd pass. Another thing that I noticed is that for lower row counts like 2000, this behavior doesn't happen and all iterations are there. I've tried to schedule the batch and also ran it manually but both have same behavior. Why is this happening? Thanks.  Here is the code:
 
global class ScheduledOpportunityTrend_Batch implements Database.Batchable<sObject> {
	String query;
   
    global ScheduledOpportunityTrend_Batch() {
        if(Test.isRunningTest()){
             query ='Select id,Name, Opportunity.Account.name, Opportunity.amount, Opportunity.CloseDate,Opportunity.CreatedDate, Opportunity.DateClosed__c, Opportunity.Name, ProductCode, Product_Code_Entry__c, Opportunity.Account.Territory__c, convertCurrency(TotalPrice), Opportunity.currencyisocode,Opportunity.id, OpportunityLineItem.Product2.Business_Unit__c from OpportunityLineItem where InQuote__c = true and OpportunityLineItem.Product2.Business_Unit__c = \'Optical\' and Opportunity.IsClosed = false ORDER BY Opportunity.Name limit 100'; 
        } else{
             query ='Select id,Name, Opportunity.Account.name, Opportunity.amount, Opportunity.CloseDate,Opportunity.CreatedDate, Opportunity.DateClosed__c, Opportunity.Name, ProductCode, Product_Code_Entry__c, Opportunity.Account.Territory__c, convertCurrency(TotalPrice), Opportunity.currencyisocode,Opportunity.id, OpportunityLineItem.Product2.Business_Unit__c from OpportunityLineItem where InQuote__c = true and OpportunityLineItem.Product2.Business_Unit__c = \'Optical\' and Opportunity.IsClosed = false ORDER BY Opportunity.Name'; 
        }
   }

    
    global Database.querylocator start(Database.BatchableContext BC){
        //Get the opportunities for Simulator that are open. We don't take into account any dates. We fetch everything.
        return Database.getQueryLocator(query);
    }
 
    global void execute(Database.BatchableContext BC, List<OpportunityLineItem> scope){
  		
         List<SnapshotOpportunityTrend__c> ObjecttoInsert = new List<SnapshotOpportunityTrend__c>();
       
        for(OpportunityLineItem s :  scope){
            //create object and set all the fields in object
                SnapshotOpportunityTrend__c SnapObject = new SnapshotOpportunityTrend__c();
                
                snapObject.Business_Unit__c = s.Product2.Business_Unit__c;
                snapObject.Opportunity_Id__c = s.Opportunity.id;
                snapObject.Opportunity__c = s.Opportunity.id;
                SnapObject.Account_Name__c = s.Opportunity.Account.name;
                SnapObject.Amount__c = s.Opportunity.amount;
                SnapObject.Amount_Currency__c = s.Opportunity.amount;
                SnapObject.Closed_Date__c = s.Opportunity.CloseDate;
                SnapObject.Created_Date__c = s.Opportunity.CreatedDate.date();
                SnapObject.Date_Closed__c = s.Opportunity.DateClosed__c;
                SnapObject.Opportunity_Name__c = s.Opportunity.Name;
                SnapObject.Product_Code__c = s.ProductCode;
                SnapObject.Product_Code_Entry__c = s.Product_Code_Entry__c;
                SnapObject.Territory__c = s.Opportunity.Account.Territory__c;
                SnapObject.Total_Price__c = s.TotalPrice;
                SnapObject.Total_Price_Currency__c = s.TotalPrice;
                    
                    ObjecttoInsert.add(SnapObject);

            system.debug('aaaaaaaa: ' + ObjecttoInsert.size());
           		
       }
 				
 			try{
                //insert list containing all lines
                insert ObjecttoInsert;
            }catch(Exception e) {
                System.debug('An exception occurred: ' + e.getMessage());
            }

    }
     
    global void finish(Database.BatchableContext BC){
        AsyncApexJob a = 
           [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,
            TotalJobItems, CreatedBy.Email
            FROM AsyncApexJob WHERE Id =
            :BC.getJobId()];
                          
       // Send an email to the Apex job's submitter 
       //   notifying of job completion. 
       Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
       String[] toAddresses = new String[] {a.CreatedBy.Email};
       mail.setToAddresses(toAddresses);
       mail.setSubject('SnapObject: ' + a.Status);
       mail.setPlainTextBody
       (query + ' : ' + a.TotalJobItems +
       ' batches with '+ a.NumberOfErrors + ' failures.' );
       Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }
}

 
Naveen IlaNaveen Ila
I hope there might be a faulty record which is causing the issue. In catch block of try-catch, try sending an email to yourself (with error details) to see there is any error.