function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Matt Cooper 7Matt Cooper 7 

De-reference a null object error when attempting to set user variable value to Owner

Hi, I'm putting together a trigger to handle some of my workflow rules (our org is hitting limits) and I keep getting the following error:
"Error:Apex trigger AR_Email_Alerts caused an unexpected exception, contact your administrator: AR_Email_Alerts: execution of AfterUpdate caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.AR_Email_Alerts: line 62, column 1"
Usually I get this error when I'm trying to set a variable value to a field that is null.  However, in this case the value I'm using is OwnerId and on a record that already exists.  Can anyone help pinpoint what might be the issue?  Thanks!
 
trigger AR_Email_Alerts on Apttus__APTS_Agreement__c (after insert, after update) {

    String[] toRecipients;
    String[] ccRecipients;
    String templateApiName;
    ID targetObjId;
    Id whatId;
    ID orgWideEmailId;
    Boolean saveAsActivity;
    Attachment[] attachList;
    Map<String, Id> typeMap = New Map<String, Id>();
    recordtype rt2;
    Map<string, id> userEmail = new map<string, id>();
 	ID rtID = Schema.SObjectType.Apttus__APTS_Agreement__c.getRecordTypeInfosByName().get('Appropriations Request').getRecordTypeID();
    
    for (Apttus__APTS_Agreement__c agmt :trigger.new){
        if (agmt.recordtypeid == rtID) {
            //Workflow rule for when AR is Activated - updates fields and sends email to AR Preparer and Requestor
            if((agmt.Apttus__Status_Category__c == 'Request' && agmt.Apttus__Workflow_Trigger_Viewed_Final__c == true)
               || (agmt.Apttus_Approval__Approval_Status__c =='Approved' && agmt.AR_Total_Appropriations_Request_Total2__c < 1000) 
               || (agmt.Apttus_Approval__Approval_Status__c =='Approved' && agmt.AR_Capital_Expenditure_Total__c <1000 && agmt.AR_Option_or_New_Lease__c =='Option')){
                   User user1;
                   User user2;
                   user1.id = agmt.Apttus__Requestor__c;
                   user2.id = agmt.AR_Preparer__c;
                   toRecipients.add(user1.email);
                   toRecipients.add(user2.email);
                   templateApiName = 'AR_Activated';
                   targetObjId = user1.id;
                   agmt.Apttus__Activated_Date__c = Date.today();
                   agmt.Apttus__Workflow_Trigger_Viewed_Final__c = false;
                   agmt.Apttus__Status__c = 'Activated';
                   agmt.Apttus__Status_Category__c = 'In Effect';
               }
            //AR Admin Tasks workflow rule - sends email to Owner/AR Admin
            else if(agmt.Apttus__Status__c == 'Approved Request' 
               && agmt.AR_Reference_Number__c == '' 
               && agmt.AR_Total_Appropriations_Request_Total2__c >= 1000 
               && agmt.AR_Option_or_New_Lease__c !='Option'){
                   User user1;
                   user1.id = agmt.Ownerid;
                   toRecipients.add(user1.email);
                   templateApiName = 'AR_Administrator_Admin_Tasks';
                   targetObjId = user1.id;
               }
            //CPMO Admin pause - sends email to Owner/AR Admin to notify the AR Admin to start the CPMO approvals
            else if(agmt.Apttus__Status__c == 'Submitted Request' 
               && agmt.Apttus_Approval__Approval_Status__c =='Not Submitted' 
               && agmt.AR_Total_Appropriations_Request_Total2__c >= 20000){
                   ID oID = agmt.Ownerid;
                   User user1;
                   user1.id = oID;
                   toRecipients.add(user1.email);
                   templateApiName = 'AR_Administrator_CPMO_Admin_Pause';
                   targetObjId = user1.id;
               }
            //Sub-committee Admin pause - sends email to Owner/AR Admin to notify the AR Admin to start the sub-committee approvals
            else if(agmt.Apttus__Status__c == 'Request Approval' 
               && agmt.Apttus_Approval__Approval_Status__c =='Not Submitted' 
               && agmt.AR_Total_Appropriations_Request_Total2__c >= 1000){
                   User user1;
                   user1.id = agmt.Ownerid;
                   toRecipients.add(user1.email);
                   templateApiName = 'AR_Administrator_Subcommittee_Admin_Pause';
                   targetObjId = agmt.Ownerid;
               }
            whatId = '01Io00000009t1OEAQ';
            orgWideEmailId = '0D2o0000000TNsu';
            sendTemplatedEmailClass.sendTemplatedEmail(toRecipients, ccRecipients, templateApiName, targetObjId, whatId, orgWideEmailId);
        }
    }

}

 
Best Answer chosen by Matt Cooper 7
James LoghryJames Loghry

So you need to do a few things if you're going to fetch the owner's email:

You'll need to requery for the Owner's email address.  The reason being is relationship's fields (in this case Owner.Email) aren't available in the trigger.

So before line 13, add the following:

Set<Id> ownerIds = new Set<Id>();
for(Apptus__APTS_Agreement__c agmt : Trigger.new){
    ownerIds.add(agmt.OwnerId);
}

Map<Id,User> ownerMap = new Map<Id,User>([Select Email From User where Id in :ownerIds]);


And then lines 50 - 55 could be replaced with:

 

User user1 = ownerMap.get(agmt.OwnerId);
if(user1 != null){
    toRecipients.add(user1.email);
    templateApiName = 'AR_Administrator_CPMO_Admin_Pause';
    targetObjId = user1.id;
}

Looks like you might have some other issues to work out, but that should fix your NullPointerException.

All Answers

James LoghryJames Loghry
The issue lies with Lines 61 and Lines 62.  You declare user1, but you never initialize it to anything, so that at line 62, it throws a NullPointerException.  Not sure what you're trying to do with user1, but it needs to be initialized or set to an existing user record.
Matt Cooper 7Matt Cooper 7
On line 62 I am trying to set the user1 variable to the user record of the Owner.  How can I set user1 to be the user record of the Owner?
Jason Reiber [ACS]Jason Reiber [ACS]
Matt,

You can try initializing it first with something like :  User user1 = new User();
James LoghryJames Loghry

So you need to do a few things if you're going to fetch the owner's email:

You'll need to requery for the Owner's email address.  The reason being is relationship's fields (in this case Owner.Email) aren't available in the trigger.

So before line 13, add the following:

Set<Id> ownerIds = new Set<Id>();
for(Apptus__APTS_Agreement__c agmt : Trigger.new){
    ownerIds.add(agmt.OwnerId);
}

Map<Id,User> ownerMap = new Map<Id,User>([Select Email From User where Id in :ownerIds]);


And then lines 50 - 55 could be replaced with:

 

User user1 = ownerMap.get(agmt.OwnerId);
if(user1 != null){
    toRecipients.add(user1.email);
    templateApiName = 'AR_Administrator_CPMO_Admin_Pause';
    targetObjId = user1.id;
}

Looks like you might have some other issues to work out, but that should fix your NullPointerException.
This was selected as the best answer
Matt Cooper 7Matt Cooper 7
Awesome thanks everyone.  I now have it firing my emails out correctly.  However, I have fields mapped into the HTML email templates that should be pulling from the record, but all of them are appearing blank.  Is there anything I can do to get those field values to appear?
Matt Cooper 7Matt Cooper 7
I was able to get the merge fields to populate by creating a fake contact and sending out an email to that contact and rolling it back.  I then copied the htmlbody and subject from the older email and sent it out to the correct email addresses. Here is the code for my controller:
 
public class sendTemplatedEmailClass {

    
//  -------------------------------------------------------------------------
//  HELPER method: sendTemplatedEmail
//  -------------------------------------------------------------------------
public static void sendTemplatedEmail(String[] toRecipients, String[] ccRecipients, String templateApiName, ID targetObjId, ID agmtID) {
	  //  templateId   must be ID of an Email template
	  //  targetObjId must be a Contact, User, Lead Id -- also used in merge fields of template recipient.xxxx
	  //  whatId    must be an SObject that is used in the merge fields of the template relatedTo.xxxx
	  //  fromId    if non null, use current user, otherwise, use this ID (most likely an org wide no reply id)
	  //  bcc      not permitted when using templates
  
	//Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
    Contact c = [select id, Email from Contact where email <> null limit 1];
    Messaging.SingleEmailMessage msg = new Messaging.SingleEmailMessage();
    List<Messaging.SingleEmailMessage> lstMsgs = new List<Messaging.SingleEmailMessage>();
    ID orgWideEmailId;
    Map<String, Id> OWE = New Map<String, Id>(); 

    
    for(OrgWideEmailAddress owa : [select id, Address, DisplayName from OrgWideEmailAddress where DisplayName = 'ECM Team']){
        OWE.put(owa.DisplayName, owa.Id);
    }
    
    orgWideEmailId = OWE.get('ECM Team');
    
    SObject s = Database.query  ('SELECT Id FROM ' +   'Apttus__APTS_Agreement__c ' +    'LIMIT 1');
   // id agmtid = s.id;
    
   // id agmtid = [SELECT Id From CustomObject Where DeveloperName = 'Apttus__APTS_Agreement__c'].id;
	Id templateId;  
	try {templateId = [select id, name from EmailTemplate where developername = : templateApiName].id;}
	catch (Exception e) {
	  System.debug ('[U-03] Unable to locate EmailTemplate using name: ' + templateApiName + 
                ' refer to Setup | Communications Templates ' + templateApiName);
	}
    // [select id from Apttus__APTS_Agreement__c limit 1].id 
	msg.setWhatId(agmtid);
	msg.setTargetObjectId(c.id);
    msg.setBccAddresses(toRecipients);
    msg.setorgWideEmailAddressId(orgWideEmailId);
    msg.setTemplateId(templateId);

    
    lstMsgs.add(msg);
    
    Savepoint sp = Database.setSavepoint();
	Messaging.sendEmail(lstMsgs);
	Database.rollback(sp);
    
    List<Messaging.SingleEmailMessage> lstMsgsToSend = new List<Messaging.SingleEmailMessage>();
    for (Messaging.SingleEmailMessage email : lstMsgs) {
        Messaging.SingleEmailMessage emailToSend = new Messaging.SingleEmailMessage();
        emailToSend.setBccAddresses(email.getBccAddresses());
        emailToSend.setPlainTextBody(email.getPlainTextBody());
        emailToSend.setorgWideEmailAddressId(email.getorgWideEmailAddressId());
        emailToSend.setHTMLBody(email.getHTMLBody());
        emailToSend.setSubject(email.getSubject());
        lstMsgsToSend.add(emailToSend);
        }
    System.debug(LoggingLevel.INFO,'** entered sendTemplatedEmail, to:' + toRecipients + ' cc:' + ccRecipients +  ' templateId:' + templateId + ' targetObjId:' + targetObjId + 
                    ' orgWideEmailId: ' + orgWideEmailId);

    try{
        Messaging.sendEmail(lstMsgsToSend);
        return;
    }
    catch (EmailException e) {System.debug('[U-02] sendTemplatedEmail error. ' + e.getMessage());}
    

}  
}