+ Start a Discussion
Jagadeesh AdaveniJagadeesh Adaveni 

Getting error "Attempt to dereference null" in Batch apex.

Hi All,

I am getting error as Attempt to dereference null while am running batch apex. Could you please resolve it
Below is my code
global class batchLogBookManagementV2 implements Database.Batchable<sObject> {

global List<Log_Book__c> logToBeContinued = new List<Log_Book__c> ();
global List<Log_Book__c> logToBeInserted = new List<Log_Book__c> ();    
global List<Subject_Registered__c> sbsr = new List<Subject_Registered__c> ();
    
    global List<Weeks__c> weekList = Weeks__c.getAll().values();
    global Map<Integer, Weeks__c> weekMap = new Map<Integer, Weeks__c>();
    global Map<String, Integer> weekMapGetIntWithWeek = new Map<String, Integer>();    
    global Map<String, Subjects_and_Levels__c> subjectLevelMap =  Subjects_and_Levels__c.getAll();
    global List<Subjects_and_Levels__c> subjectLevelList = subjectLevelMap.values();
    global Map<String, Subjects_and_Levels__c> levelMap = new Map<String, Subjects_and_Levels__c>();
        
global final String query = 'SELECT id, Last_Schedule__c, Level__c, Student__c, Subject__c, Week__c, (SELECT Student__c, Subjects_Registered__c, Subject__c, Class_Scheduled_Date__c, Level__c, Week__c FROM Log_Books__r ORDER By Class_Scheduled_Date__c DESC NULLS FIRST LIMIT 1 ) FROM Subject_Registered__c WHERE Deactivated__c = false AND Last_Schedule__c != null';
 
 
global Iterable<sObject> start(Database.BatchableContext BC){
     sbsr = Database.query(query);
     for(Subject_Registered__c s: sbsr)
     {
         logToBeContinued.add(s.log_Books__r[0]);         
     }
    
    return logToBeContinued;
    }
 
global void execute(Database.BatchableContext BC,List<Log_Book__c> scope){
     for(Subjects_and_Levels__c level: subjectLevelList)
     {
     system.debug('level : '+level);
         if(level !=null)
         levelMap.put(level.subject__c+Integer.valueof(level.Order__c), level);
         else
             system.debug('error as level null');
     }
    for(Weeks__c week : weekList)
    {
    system.debug('week : '+week);
        if(week != null){
            weekMap.put((Integer)week.Order__c, week);
            weekMapGetIntWithWeek.put(week.Name, (Integer)week.Order__c);
        }
    }
     System.debug('++++++++++++++++++++++++   : ' + scope);
     for(Log_Book__c s: scope)
     {
         
         System.debug('logToBeInserted--------------------------------   : ' + logToBeInserted.size());
         System.debug('--------------------------------   : ' + s);
         Integer totalLevels = 0;
          if(s.Subject__c == 'English')
            totalLevels = 16;
          else if(s.Subject__c == 'Abacus')
            totalLevels = 11;
          else if(s.Subject__c == 'Math')
            totalLevels = 14;
          else if(s.Subject__c == 'G.K')
            totalLevels = 3;
         System.debug('xxxxxxxxxxxxxxxx  : ' + subjectLevelMap);
         //System.debug('@@Subject@@@@@@@'+subjectLevelMap.get(s.Subject__c+s.level__c));
         
             Integer levelOrder = Integer.valueof(subjectLevelMap.get(s.Subject__c +':'+s.Level__c).Order__c);
             system.debug('level order: '+levelOrder);
             Integer weekOrder = Integer.ValueOf(weekMapGetIntWithWeek.get(s.Week__c));
             system.debug('week order: '+weekOrder);
         
         Log_Book__c l = new Log_Book__c ();
         l.Student__c = s.Student__c;
         l.Subject__c = s.Subject__c;
         l.Subjects_Registered__c = s.Subjects_Registered__c;
         l.Class_Scheduled_Date__c = s.Class_Scheduled_Date__c.addDays(7);
           
         if(s.Week__c == '26-Z')
         {
             if(levelOrder < totalLevels)
             {
                 levelOrder = levelOrder +1;
                 System.Debug('lb.Subject__c+levelOrder : '+ l.Subject__c+levelOrder);
                 l.level__c = levelMap.get(l.Subject__c+levelOrder).Level__c;
                 l.Week__c = '1-A';
                 logToBeInserted.add(l);
             }
             
         }
         else
          if(s.Subject__c == 'Math' && s.Level__c == 'Level 5B' && s.Week__c == '17-Q')
            {
              if(levelOrder < totalLevels)
             {
                 levelOrder = levelOrder +1;
                 System.Debug('lb.Subject__c+levelOrder : '+ l.Subject__c+levelOrder);
                 l.level__c = levelMap.get(l.Subject__c+levelOrder).Level__c;
                 l.Week__c = '1-A';
                 logToBeInserted.add(l);
             }
       
            }
         else
         {
                weekOrder = weekOrder+1;
                l.Week__c = weekMap.get(weekOrder).Name;
                l.Level__c = s.Level__c;
                logToBeInserted.add(l);
                    
         }
         
         
     }
    if(logToBeInserted.size()>0)
    {
               
        Database.SaveResult[] srList = Database.insert(logToBeInserted, false);
        
        // Iterate through each returned result
        for (Database.SaveResult sr : srList) {
            if (sr.isSuccess()) {
                // Operation was successful, so get the ID of the record that was processed
                System.debug('Successfully inserted LogBook. LogBook ID: ' + sr.getId());
            }
            else {
                // Operation failed, so get all errors                
                for(Database.Error err : sr.getErrors()) {
                    System.debug('The following error has occurred.');                    
                    System.debug(err.getStatusCode() + ': ' + err.getMessage());
                    System.debug('Account fields that affected this error: ' + err.getFields());
                }
            }    
        
        }
        
    }
    //  System.debug('###############################  :' + ((Subject_Registered__c)scope.get(0)).log_Book__r.Class_Scheduled_Date__c);
    // scope variable now has the records received from QueryLocator.
  //  delete scope;    
   // Database.emptyRecycleBin(scope);
    }
 
global void finish(Database.BatchableContext BC){
AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed, TotalJobItems, CreatedBy.Email FROM AsyncApexJob WHERE Id =:BC.getJobId()];
 
    // Send an email to the Apex job's submitter
    // notifying of job completion.
  
 Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
 String[] toAddresses = new String[] {a.CreatedBy.Email};
 mail.setToAddresses(toAddresses);
 mail.setSubject('BAtch: ' + a.Status);
 mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems +' batches with '+ a.NumberOfErrors + ' failures.');
 Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
  }
}
 Below are my custom settings

User-added image

Thanks,
Jagadeesh
Best Answer chosen by Jagadeesh Adaveni
Praveen KHariPraveen KHari
Hi Jagadeesh,

As i mentioned earlier you have values in "subjectLevelMap" varibale but its failed to fetch the record matching with the key you provided. Please print your key and verify your custom sesttings for the key combination. If you just want to stop getting this null pointer exception, use a IF condition.

-Praveen K Hari

All Answers

Praveen KHariPraveen KHari
Hi Jagadeesh,

Null pointer exception happens when you try to do any operation on a null value object. Salesforce debug log will give more information like line number etc.… Run your batch class on debug mode (adding running user to debug logs) and find out the line number which throws null value error. To solve the issue add IF before the line based on batch class logic.

-Praveen K Hari
 
Jagadeesh AdaveniJagadeesh Adaveni
Hi Praveen,

I am gettng error at line number 62,, means unable to get values from custom settings. But i have value in custom setting.

Thanks,
A.Jagadeesh
Praveen KHariPraveen KHari
I recommend you to use system.debug() method and print your values and make sure you are passing correct values to the map. Alos please share the debug statement result you have added to line number 58.

I doubt that this can be due to missing Database.Stateful in your class. Please read below link for more details

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_batch_interface.htm
Jagadeesh AdaveniJagadeesh Adaveni
In System.debug am getting below statements.

User-added image
Bhaswanthnaga vivek vutukuriBhaswanthnaga vivek vutukuri

line 61 check

if(subjectLevelMap.containsKey(s.Subject__c+':'+s.Level__c)) {

Integer levelOrder = Integer.valueof(subjectLevelMap.get(s.Subject__c+':'+s.Level__c).Order__c);
 }

Praveen KHariPraveen KHari
Hi Jagadeesh,

As i mentioned earlier you have values in "subjectLevelMap" varibale but its failed to fetch the record matching with the key you provided. Please print your key and verify your custom sesttings for the key combination. If you just want to stop getting this null pointer exception, use a IF condition.

-Praveen K Hari
This was selected as the best answer
Jagadeesh AdaveniJagadeesh Adaveni
Hi Bhaswanthnaga vivek vutukuri, Praveen KHari,

Written if condion like below then i didn't get any error.
if(subjectLevelMap.containsKey(s.Subject__c+':'+s.Level__c)) {
-----------------
-----------------
}

Shall i need to write else block if yes what can i add in else block.
Bhaswanthnaga vivek vutukuriBhaswanthnaga vivek vutukuri

Put all these lines under if

if(subjectLevelMap.containsKey(s.Subject__c+':'+s.Level__c)) {
             Integer levelOrder = Integer.valueof(subjectLevelMap.get(s.Subject__c +':'+s.Level__c).Order__c);
             system.debug('level order: '+levelOrder);
             Integer weekOrder = Integer.ValueOf(weekMapGetIntWithWeek.get(s.Week__c));
             system.debug('week order: '+weekOrder);
         
         Log_Book__c l = new Log_Book__c ();
         l.Student__c = s.Student__c;
         l.Subject__c = s.Subject__c;
         l.Subjects_Registered__c = s.Subjects_Registered__c;
         l.Class_Scheduled_Date__c = s.Class_Scheduled_Date__c.addDays(7);
           
         if(s.Week__c == '26-Z')
         {
             if(levelOrder < totalLevels)
             {
                 levelOrder = levelOrder +1;
                 System.Debug('lb.Subject__c+levelOrder : '+ l.Subject__c+levelOrder);
                 l.level__c = levelMap.get(l.Subject__c+levelOrder).Level__c;
                 l.Week__c = '1-A';
                 logToBeInserted.add(l);
             }
             
         }
         else
          if(s.Subject__c == 'Math' && s.Level__c == 'Level 5B' && s.Week__c == '17-Q')
            {
              if(levelOrder < totalLevels)
             {
                 levelOrder = levelOrder +1;
                 System.Debug('lb.Subject__c+levelOrder : '+ l.Subject__c+levelOrder);
                 l.level__c = levelMap.get(l.Subject__c+levelOrder).Level__c;
                 l.Week__c = '1-A';
                 logToBeInserted.add(l);
             }
       
            }
         else
         {
                weekOrder = weekOrder+1;
                l.Week__c = weekMap.get(weekOrder).Name;
                l.Level__c = s.Level__c;
                logToBeInserted.add(l);
                    
         }
         }
Jagadeesh AdaveniJagadeesh Adaveni

Hi Bhaswanthnaga vivek vutukuri, Praveen KHari,



As i pulled all the code under if condition. Working fine but again getting error like below. total 36 batches are there in that 2 failueres are coming.
User-added image

Thanks,
A.Jagadeesh.
Praveen KHariPraveen KHari
 
You might have already noticed the exception details. It’s says you can’t not use ID value in an insert call. So we can use upset statement instead of Database.Insert
Replace line number 112 with below code
Database.UpsertResult srList  = Database.upsert(logToBeInserted,false);
 
Also change the type of srList to UpsertResult. So make necessary changes in line number 115 etc..
Jagadeesh AdaveniJagadeesh Adaveni
shall i remove id in the query? because i am not updating anything it's related to insert statement.