1
global class NotifyBatch2 implements Database.Batchable<sObject>,Database.Stateful {

/public string query = 'select Id, name,Status__c,CreatedDate  from MR_Product__c where Status__c= \'Pending Submission\' And CreatedDate=System.today()-CreatedDate>24';
datetime dt = System.now()-1;
public string query = 'select Id, name,Status__c,CreatedDate,Materials_Meeting_Date__c,Materials_Due_Date__c,CreatedBy.Email,Submitter__c,Book_Coverage__c,Notes__c,Materials_Request_Organization__c from MR_Product__c where Status__c=\'Pending Submission\'';
//And CreatedDate >:dt';


public transient List<Messaging.SingleEmailMessage>  mails = new List<Messaging.SingleEmailMessage>();



global database.querylocator start(Database.BatchableContext BC)
{
  System.debug('CheckRecords:' + query);

    return Database.getQueryLocator(query);
}

global void execute(Database.BatchableContext BC, Sobject[] scope)
{ 



    EmailTemplate emailTemplate = [select Id, Body  from EmailTemplate where DeveloperName = 'BOOK_REQUEST_Template'];

    for (MR_Product__c  item : (List<MR_Product__c>)scope) {


            Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
             string MatDueDate = string.valueOfGmt(item.Materials_Due_Date__c);
             string MatMeetingDate = string.valueOfGmt(item.Materials_Meeting_Date__c);      

                    string body = emailTemplate.body;

                    body  = body.replace('{!MR_Product__c.Submitter__c}', item.Submitter__c);
                    body  = body.replace('{!MR_Product__c.Materials_Request_Organization__c}', item.Materials_Request_Organization__c);
                    body  = body.replace('{!MR_Product__c.Materials_Due_Date__c}', MatDueDate );
                    body  = body.replace('{!MR_Product__c.Materials_Meeting_Date__c}', MatMeetingDate);

                    if(item.Notes__c!=null && item.Notes__c!=''){
                    body  = body.replace('{!MR_Product__c.Notes__c}', item.Notes__c);
                    }
                     if(item.Book_Coverage__c!=null && item.Book_Coverage__c!=''){
                    body  = body.replace('{!MR_Product__c.Book_Coverage__c}', item.Book_Coverage__c);

                    }

                    email.setToAddresses(new String[] {item.createdby.Email});
                    email.setSaveAsActivity(false);
                    email.setPlainTextBody(body);
                    //email.setTargetObjectId(item.id);
                    email.setTemplateId(emailTemplate.Id);
                    //email.setWhatId(item.Id);
                    system.debug('Checkemails' + email);
                    mails.add(email);

          // Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});



    }





}

global void finish(Database.BatchableContext BC) {


    Messaging.sendEmail(mails);



}




}

I'm trying to execute this batch apex class. All I want is to do is send emails in the finish method but whenever I declare the list (mails) at global level a null pointer exception is thrown. Find the error message below:

Class.MaterialRequestNotifyBatch2.execute: line 58, column 1

on line number 58 I have the following code: mails.add(email);

3
  • Try Removing the transient keyword, that's the only bit that doesn't make sense to me right now.
    – d_k
    Apr 20, 2017 at 9:46
  • If i remove transient keyword its shows : First error: Not Serializable: com/salesforce/api/fast/List$$lcom/salesforce/api/Messaging/SingleEmailMessage$$r
    – Prateek
    Apr 20, 2017 at 9:53
  • This question displays more or less the same problem as salesforce.stackexchange.com/q/137323/2995
    – Adrian Larson
    Apr 20, 2017 at 13:16

2 Answers 2

1

I recollect that email messages are not serializable which may be why transient has been added.

So instead create your own class (can be a nested class of NotifyBatch2) that has the required attributes to capture the information you want to email and add to a list of those declared as a non-transient class property. Then in the finish method convert those objects to Messaging.SingleEmailMessage objects and send them.

0

transient variables has a local access. So even if you have declared it globally, it will store null value inside the method execute, as it is not initialized there. For that same reason it will not get null pointer in the Messaging.sendEmail(mails); next.

You have one possible way to do this -

Try initialize within execute method. Also use the Messaging.sendEmail(mails); within this execute method.

You must log in to answer this question.

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