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
suji srinivasansuji srinivasan 

Hi ,my Batch apex is not working if i scheduled it ,it stays in queue for long time .In queue it shows total batch processed zero

I couldnt see debug statements aswell. its not showing error got 100% coverage. when i use database.execute batch totalbatch processed it shows 1 and zero failures. only after schedule it shows  total batch zero in apex jobs.can anyone guide me to resolve this issue?

global class UpdateAccountRating implements Database.Batchable<sObject> {
   
 global  Database.QueryLocator start(Database.BatchableContext bc) {
     set<string> strlist = new set<string>{'workInprogress','Delivered','ClosedWon'};
      string query='select id, stageName,AccountId, Account.Rating from opportunity where stageName IN :strlist AND AccountId !=Null';
     system.debug('query=='+query);
     return Database.getQueryLocator(query); 
    }
     global Void execute(Database.BatchableContext bc, List<opportunity> Scope){
      
        for(opportunity o :Scope){
            o.Account.Rating='client';  
          system.debug('Rating'+o.Account.Rating);
           
        }
         update Scope;}
         global void finish(Database.BatchableContext bc){
       
        AsyncApexJob job = [SELECT Id, Status,NumberOfErrors,JobItemsProcessed,TotalJobItems, CreatedBy.Email 
                            FROM AsyncApexJob
                            WHERE Id = :bc.getJobId()];  
    }   
     } 

testclass
@isTest
public class UpdateAccountRatingTest {
    @isTest
    public static void unit_test(){
      
        Account acc =new Account();
        acc.Name = 'test';
        acc.Rating='prospect';
        insert acc;
        
        
        Opportunity opp = new opportunity();
        opp.Name = 'test opp';
        opp.Accountid = acc.Id;
        opp.stageName = 'workInprogress';
        opp.CloseDate = system.today()+5;
        insert opp;
         
       
        
        Test.startTest();
      
        UpdateAccountRating uar  = new UpdateAccountRating();
        Database.executeBatch(uar);
      String sch = '0 0 0 1 * ? *';
      string JobID = system.schedule('BatchJob',sch, new UpdateAccountRatingSchedular());
        Test.stopTest();
       

 }
    }
schedular
global class UpdateAccountRatingSchedular implements Schedulable {
global void execute(SchedulableContext sc){
        UpdateAccountRating uar = new UpdateAccountRating();
        database.executebatch(uar);
    }
}


Thanks in advance
Best Answer chosen by suji srinivasan
suji srinivasansuji srinivasan
I resolved it by writing seperate soql for Account and Opportunity  .Thank you for your support.
global  Database.QueryLocator start(Database.BatchableContext bc) {
List<Id> accId = new List<Id>();
     for(Opportunity O:[select Id,AccountId from Opportunity where StageName ='Delivered' OR StageName ='Closed Won' OR StageName = 'Work In Progress']){
         accId.add(O.AccountId);
     }
        string query='select ID,Name,Rating from Account where ID IN:accId';

All Answers

Antoninus AugustusAntoninus Augustus
Hi I made some updates to your 'UpdateAccountRating' class.
public class UpdateAccountRating implements Database.Batchable<sObject> {
    
    public  List<Opportunity> start(Database.BatchableContext bc) {    
        Set<String> stageNames = new Set<String>{'workInprogress','Delivered','ClosedWon'};
        return [SELECT ID, Account.Rating FROM Opportunity WHERE stageName IN :stageNames AND AccountId != NULL];
    }
    public void execute(Database.BatchableContext bc, List<opportunity> opportunities) {
        List<Account> accountsToUpdate = new List<Account>();
        for(Opportunity objOpportunity : opportunities){
            objOpportunity.Account.Rating='client';
            accountsToUpdate.add(objOpportunity.Account);
        }
        update accountsToUpdate;
    }
    public void finish(Database.BatchableContext bc){}   
}

To be able to update the 'Rating' field on the parent Account object you would need to update the Accounts directly and not the Opportunities.
As for the scheduling issue, you might be scheduling it incorrectly. Look at the CronTrigger DOCS (https://developer.salesforce.com/docs/atlas.en-us.238.0.object_reference.meta/object_reference/sforce_api_objects_crontrigger.htm) for help on how to properly schedule it.
 
suji srinivasansuji srinivasan
Hi , Thank you for your response.I scheduled it for 5 minutes .In debug logs i could see rating client. but it stays on queue for long not making changes
suji srinivasansuji srinivasan
system.schedule('BatchJobS','0 05 * * * ?', new UpdateAccountRatingSchedular());
this i used for scheduling.
User-added image

it is not making changes as expected but got output in debuglog
suji srinivasansuji srinivasan
I resolved it by writing seperate soql for Account and Opportunity  .Thank you for your support.
global  Database.QueryLocator start(Database.BatchableContext bc) {
List<Id> accId = new List<Id>();
     for(Opportunity O:[select Id,AccountId from Opportunity where StageName ='Delivered' OR StageName ='Closed Won' OR StageName = 'Work In Progress']){
         accId.add(O.AccountId);
     }
        string query='select ID,Name,Rating from Account where ID IN:accId';
This was selected as the best answer