0

In the below batch apex class I'm not able to store different batches or transaction records in the global list, I used database.stateful also still I don't know why??????

Currently I'm getting records of last batch or transaction only.

  global class ManagementBatch implements Database.Batchable<sObject>,Database.Stateful{
        
        private String query;
        global List<Application__c> glApplicationRecordstoUpdate; 
        
       
        global ManagementBatch() {
           
            query = 'SELECT Id, AccountId, ContactId, Contact.FirstName, Record_Id__c,Account.Name, Contact.MiddleName,Contact.LastName, Contact.email, Roles,';
          
            
        }
        
       
        global Database.QueryLocator start(Database.BatchableContext BC) {   
            return Database.getQueryLocator(query);    
        }
    
      
        global void execute(Database.BatchableContext BC, List<AccountContactRelation> scope) {
            List<Application__c> applicationRecordstoUpdate=new List<Application__c>();
            applicationRecordstoUpdate=ManagementUtil.findCommunityUsers(scope, null);
   // here the records are storing to golbal but records i'm not getting stored from different batches i don't know 
            glApplicationRecordstoUpdate.addAll(applicationRecordstoUpdate);
            
        } 
        global void finish(Database.BatchableContext BC){
           
        }
    }
4
  • Can you initiate list in controller??
    – Ysr Shk
    Apr 14 at 12:05
  • If I declare list in controller that will work ?
    – Ravi Kumar
    Apr 14 at 12:22
  • How are you getting access to the Batchable implementation instance (your ManagementBatch instance)?
    – Phil W
    Apr 14 at 12:35
  • As an aside: Why are you using "global" scope? Does this class and its attributes and methods need to be visible across a namespace boundary? See documentation where Salesforce recommends against use of "global". This is there for exposing APIs from managed packages and for allowing managed packages to instantiate subscriber apex classes only. You almost certainly don't need global.
    – Phil W
    Apr 14 at 12:38
2

Regardless of access modifier, non-static attributes in an Apex class are specific to a given instance of that class.

Now some things to understand about Batchables:

  1. Calling Database.executeBatch simply serializes your Batchable implementation instance into the database.
  2. At some later point the Batchable is deserialized from the database (in a new session**) and the start method is invoked. The query locator returned is used to generate a cache of the IDs of all matching records, and this cache is stored away for processing later.
  3. At some later point the Batchable is deserialized from the database (in a new session) and the execute method is invoked with the first chunk of objects built from the first n IDs from the cache of IDs (and these are then removed from that cache). This repeats (asynchronously, one session per call) until the cache of IDs is empty.
  4. At some later point the Batchable is deserialized from the database (in a new session) and the finish method is invoked.

Declaring your Batchable as implementing Database.Stateful simply means that each time start or execute returns, the new state for the Batchable instance is re-serialized to the database for use when deserializing again.

Each deserialized instance is actually a completely new, in-memory instance of your apex class.

So, just because you make an attribute "global", you don't make this available as the same list in every use of your Batchable. (You probably shouldn't be using "global" anyway. See the documentation.) Making the attribute "public" won't do this either, and nor will making it "public static".

Static members are "shared" between all instances of a given Apex class, but ONLY IN THE SAME SESSION. Each session against the Salesforce platform (and that includes the separate sessions for start, each execute and finish) gets its own version of this static variable.

It seems like you were expecting your "global" list to be shared across all instances of your class; this simply isn't what happens, and you cannot use "static" to do this either.

Your list will be fully populated for this given batch's execution in the finish method and will then disappear.

**: A "session" is a single invocation of processing on the Salesforce platform. This can be initiated from the UI (e.g. when saving a record), a REST or Web Service API, a (set of) platform event(s) or some form of async processing (future, queueable, batch).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.