How To Use Database.Stateful Interface In Batch Apex In Salesforce : Kirandeep

How To Use Database.Stateful Interface In Batch Apex In Salesforce
by: Kirandeep
blow post content copied from  Forcetalks
click here to view original post


1. In Batch apex Changes made by one execute do not transfer to the other execute, so we need to implement  “Database.Stateful” if the batch process needs information that is shared across transactions.

In other words, If you want to transfer the state of the data from one batch to another batch we need to implement “Database.Stateful” interface.

2. If a batch apex class implements “Database.Stateful” interface, the state of the non-static data will be transferred from one execute method to another execute method.

For example:

If we want to check the number of record pass and failed in a batch job, in this particular scenario we need to implement Stateful interface

Example1: Create a custom object “optytmp” with the custom field “Totalamount1”.

Summarize the amount of all the opportunities and create a new optytmp record with an amount as the summarized value of the opportunity.

dont miss out iconDon't forget to check out: Future Methods in Apex | The Salesforce Developer Guide

If we don’t use Database.stateful interface the “Totalamount1” will be Zero as execute method will not pass the data to the finish method.

global class Optystate implements Database.Batchable<Sobject>,Database.stateful {
    global decimal total=0;
    global database.QueryLocator start(database.BatchableContext bc){
        return database.getQueryLocator('select name,amount from opportunity');
    }
    global void execute(database.BatchableContext bc,list<opportunity> op){
        for(opportunity o:op){
            if(o.Amount!=null){
                total=total+o.amount;
            }
        }
        system.debug('=================================== in execute'+total);
    }
    global void finish(database.BatchableContext bc){ system.debug('=================================== in finish'+total); 
    optytmp__c opty=new optytmp__c();
    opty.name='Ravi';
    opty.TotalAmount1__c=total;
    insert opty;
}

Example 2: Calling one batch apex from another and passing the value through constructor.

global class Optystate implements Database.Batchable<Sobject>,Database.stateful {
    global decimal total=0;
    global database.QueryLocator start(database.BatchableContext bc){
        return database.getQueryLocator('select name,amount from opportunity');
    }
    global void execute(database.BatchableContext bc,list<opportunity> op){
        for(opportunity o:op){
            if(o.Amount!=null){
                total=total+o.amount;
            }
        }
        system.debug('=================================== in execute'+total);
    }
    global void finish(database.BatchableContext bc){
        system.debug('=================================== in finish'+total); optytmp__c opty=new optytmp__c();
        opty.name='Test';
        opty.TotalAmount1__c=total;
        insert opty;
        optystate2 os1=new optystate2(total);
        database.executeBatch(os1);
    }
}
global class Optystate2 implements Database.Batchable<Sobject> {
    global decimal total2;
    global Optystate2(decimal total1) {
        total2=total1;
    }
    global database.QueryLocator start(database.BatchableContext bc){
        return database.getQueryLocator('select name,amount from opportunity');
    }
    global void execute(database.BatchableContext bc,list<opportunity> op){
        system.debug('=================================== in finish'+total); optytmp__c opty=new optytmp__c();
        opty.name='Test1'; opty.TotalAmount1__c=total2; insert opty;
    }
    system.debug('=================================== in execute'+total);
    global void finish(database.BatchableContext bc){}
    global class  CheckpassFailBatch Update implements Database.Batchable<sObject>, Database.Stateful {
        global String log = ''; // stateful variable to keep track of errors across batches
        global Database.QueryLocator start(Database.BatchableContext BC){
            String query = 'SELECT Id, Name, NBType__c ';
            query += 'FROM Opportunity ';
            query += 'WHERE ContractStartDate__c != null ';
            query += 'AND ContractStartDate__c > 2014-01-01 ';
            //query += 'AND NBType__c != null ';
            return Database.getQueryLocator(query);
        }
        global void execute(Database.BatchableContext BC, List<sObject> scope){
            system.debug('Processing ' + scope.size() + ' opportunities');
            for (Opportunity opportunity : (List<Opportunity>)scope){
                system.debug('Processing ' + opportunity.Name);
                opportunity.NBType__c = null;
            }
            Database.SaveResult[] srList = database.update(scope, false); // allOrNone = false
            for (Integer i = 0; i < srList.size(); i++)
            if (!srList[i].isSuccess())
            this.log += '\n Error in Opportunity: ' + scope[i].name + '. Error msg=' +
            srList[i].getErrors()[0].getMessage();
        }
    }
}

dont miss out iconCheck out another amazing blog by Kirandeep here: Salesforce Apex Winter Release 21 - All You Need To Know

The post How To Use Database.Stateful Interface In Batch Apex In Salesforce appeared first on Forcetalks.


January 05, 2021 at 10:13PM
Click here for more details...

=============================
The original post is available in Forcetalks by Kirandeep
this post has been published as it is through automation. Automation script brings all the top bloggers post under a single umbrella.
The purpose of this blog, Follow the top Salesforce bloggers and collect all blogs in a single place through automation.
============================

Salesforce