I'm working on a CSV parser that I now want to handle the processing of more records.

By doing so I'm porting my existing apex class to a batch class.

I execute my batch with: Database.executeBatch(new CSVMachineBatcher(bodyLines), batchNumber);

Where bodyLines is \n separated rows from a CSV.

In the constructor I set the bodyLinesReceived received from the above executeBatch to a new public variable bodyLines in batch class.

    public List<string> bodyLines{get;set;}
    global CSVMachineBatcher(List<String> bodyLinesReceived){
        bodyLines = bodyLinesReceived;

In my batch class (CSVMachineBatcher) start method I get the column headers to know which fields these values map to by doing the following:

public Map<Integer,String> headerMap{get;set;}

global List<String> start(Database.BatchableContext BC){ 
    headerMap = new Map<String,String>();

    List<string> headerKeys = bodyLines[0].split(',');
    for (integer key=0; key < headerKeys.size(); key++) {
        headerMap.put(key, headerKeys[key].trim());

    system.debug('headerMap: ' + headerMap);


    return bodyLines;

With every iteration of a batch I execute (essentially converting each "row" of CSV into an sObject:

global void execute(Database.BatchableContext BC, List<String> scope){

    bodyLines = scope; 

    for(row=0; row < bodyLines.size(); row++) {

            System.debug('Value Line: '+ bodyLines[row]);



Where I subsequently call on the headerMap generated in the start function to find out which field the currently value relates to based on it's position. Ex: If I'm on the third row parsing this row and the value is 15 and the third row in the headerMap is Age__c I know to populate the Age__c field with this value:

String currentKey = headerMap.get(i);

However, after the first batch iteration the headerMap is returning null. Resulting in Attempt to de-reference null object error when attempting to get the value from the map based on the key.

Do public Maps or other primitive type variable not persist in a Batch Class?

  • 1
    I assume you mean column, not row ; does your batch class implement Database.Stateful ?. Also, your headerMap would be more understandable if Map<Integer,String> fieldnameByTokenPosition – cropredy Apr 15 '20 at 0:34
  • I do mean row, after I extract the column headers from row 0, I am parsing and consuming each row. Will update to integer, that was pretty dumb of me. – S.B. Apr 15 '20 at 1:49

Variables only maintain state in a batch class if the batch class implements Database.Stateful

Credit: @cropredy

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.