Batch Apex & First error: Attempt to de-reference a null object!
I stumbled upon a strange Batch Apex issue today. My batch job was going well in a few SFDC orgs; after deploying the same to a new org it stopped working completely. I just see, “First error: Attempt to de-reference a null object” in debug and apex logs. After adding a lot of debug statements in both start() and execute() methods, I found that “execute(Database.BatchableContext BC, List<Sobject> scope)” is never called after creating QueryLocator in start().
So, finally after searching on dev forums found this solution; it says don’t query NULL columns/fields in initial SOQL i.e. the SOQL string given to QueryLocator in start(). This fixed my problem.
So to put it all together in a clean way. We usually have batch jobs written in the following manner:
global class MyCoolBatch implements Database.Batchable{
global Database.QueryLocator start(Database.BatchableContext BC){
String query = 'Select X, Y, Z From Contact WHERE ...';
Database.Querylocator qr = Database.getQueryLocator(query);
return qr;
}
global void execute(Database.BatchableContext BC, List scope){
// process the records in scope, as per biz logic
}
global void finish(Database.BatchableContext BC){}
}
Here we are querying fields X, Y, and Z from Contact; in case any of X, Y, or Z are NULL in any records, you will face the “First error: Attempt to de-reference a null object” issue. Solutions to this problem are:
Add null checks in SOQL, for fields that could go NULL for ex. X != null. This might not be possible, as this will for sure change the records returned from the SOQL.
Don’t query the fields that could possibly be NULL in start() method, re-query those in “execute(Database.BatchableContext BC, List<Sobject> scope)” method. This should be safer, as execute() will always be working on a smaller subset of records for ex. 200 records.
I used the latter option i.e. don’t query NULLABLE fields in start() & re-query those fields in execute() method, this fixed the problem!