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, 2020 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, 2020 at 1:49

1 Answer 1


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

Credit: @cropredy

You must log in to answer this question.

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