1

In batch apex we want to maintain flag to keep track on records that has been processed before to avoid duplicate conversion in case batch fails half the route and we have to execute that again.

Below is my code. In if condition I am checking for the flag value not true and as soon as it enters that if I am changing that value to true and updating ctb. This is not throwing any error but not updating checkbox field.

    global class caseToBe implements Database.Batchable<sObject>, Database.Stateful {

    Integer totalRecordsInserted = 0;
    Integer totalRecordsFailed = 0;



    global Iterable<sObject> start(database.BatchableContext BC)
    {
        system.debug('Start Called');
        return Database.getQueryLocator([select Name,Accounting_Date__c,Balance_Due__c,Temp__c,Agency_Name__c from CaseToBe__c where Name != NULL]);
    }

    global void execute(Database.BatchableContext BC, List<CaseToBe__c> scope)
    {
        system.debug('Execute Called');

        List<Case> ToInsertCaseList = new List<Case>();
        for(CaseToBe__c ctb : scope)
            if(ctb.converted__c != True){
            ctb.converted__c = True;
                update ctb;
        {
            system.debug('In Loop');
            ToInsertCaseList.add(
                new case(
                    Account_Number__c = ctb.Name,
                    Balance_Due__c  = ctb.Balance_Due__c,
                    AccountId = ctb.Agency_Name__c,
                    Status = 'Working',
                    Origin = 'Web'

                ));
        }
            }
        insert ToInsertCaseList;

    } 

    global void finish(database.BatchableContext BC)
    {
        system.debug('Finish Called');
        AsyncApexJob a = [Select Id, Status, NumberOfErrors,JobItemsProcessed, TotalJobItems, CreatedBy.Email 
                          from AsyncApexJob where Id = 
                          :BC.getJobId()];


        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        String[] toAddresses = new String[] {a.Createdby.Email};
            mail.setToAddresses(toAddresses);
        mail.setSubject('Apex sharing Recalculation' + a.Status);
        mail.setplainTextBody('The Batch Apex Job has been processed' + a.TotalJobItems + 'batches with' + a.NumberOfErrors + 'failures');
        Messaging.sendemail(new Messaging.SingleEmailMessage[] {mail});
    } 
}
5
  • Above code is working as it is. Somehow my browser was cached and not showing correct result. Can anyone suggest what to do with this question? Delete or answer it?
    – Ricky
    Feb 22, 2017 at 15:39
  • I'm not sure this is worth keeping around. You can answer it if you like; I often find that I run into my old answers years later and it reminds me where I went wrong. FYI: Get rid of the DML inside the for loop. You're going to blow up governor limits in your batch.
    – sfdcfox
    Feb 22, 2017 at 15:51
  • Thanks for your comment, That is a good point. Can you help how can I take it outside the for loop? May be post that an answer?
    – Ricky
    Feb 22, 2017 at 16:03
  • Just delete update ctb; and add update scope; after the loop. You can include this your own answer.
    – sfdcfox
    Feb 22, 2017 at 16:10
  • Excellent. That worked for me.
    – Ricky
    Feb 22, 2017 at 16:54

1 Answer 1

0

Above code works on its own. As commented by @sfdcfox I am posting an update after moving DML operation out of loop.

    global class caseToBe implements Database.Batchable<sObject>, Database.Stateful {

    Integer totalRecordsInserted = 0;
    Integer totalRecordsFailed = 0;



    global Iterable<sObject> start(database.BatchableContext BC)
    {
        system.debug('Start Called');
        return Database.getQueryLocator([select Name,Accounting_Date__c,Balance_Due__c,Temp__c,Agency_Name__c from CaseToBe__c where Name != NULL]);
    }

    global void execute(Database.BatchableContext BC, List<CaseToBe__c> scope)
    {
        system.debug('Execute Called');

        List<Case> ToInsertCaseList = new List<Case>();
        for(CaseToBe__c ctb : scope)
            if(ctb.converted__c != True){
            ctb.converted__c = True;

        {
            system.debug('In Loop');
            ToInsertCaseList.add(
                new case(
                    Account_Number__c = ctb.Name,
                    Balance_Due__c  = ctb.Balance_Due__c,
                    AccountId = ctb.Agency_Name__c,
                    Status = 'Working',
                    Origin = 'Web'

                ));
        }
            }
        insert ToInsertCaseList;
    update Scope;

    } 

    global void finish(database.BatchableContext BC)
    {
        system.debug('Finish Called');
        AsyncApexJob a = [Select Id, Status, NumberOfErrors,JobItemsProcessed, TotalJobItems, CreatedBy.Email 
                          from AsyncApexJob where Id = 
                          :BC.getJobId()];


        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        String[] toAddresses = new String[] {a.Createdby.Email};
            mail.setToAddresses(toAddresses);
        mail.setSubject('Apex sharing Recalculation' + a.Status);
        mail.setplainTextBody('The Batch Apex Job has been processed' + a.TotalJobItems + 'batches with' + a.NumberOfErrors + 'failures');
        Messaging.sendemail(new Messaging.SingleEmailMessage[] {mail});
    } 
}

You must log in to answer this question.

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