I'm running a batch update on tasks and my task trigger handler is throwing a null pointer exception error. If I go through and update the tasks individually, I don't have any issues with them. If I run a batch of 2000, 1600 will update and 400 will throw the error. I'm completely at a loss why this is happening.
The following line is where I'm getting the null pointer errors:
if(String.ValueOf(t.WhatId).left(3) == '003'){
Complete code:
public class TaskTriggerHandler {
String stdRecTypeId = [SELECT id from RecordType WHERE sObjectType = 'Task' AND Name = 'Standard'].id;
//execute after insert/after update
public void isAfterInsertTask(Map<Id, Task> newTaskTriggerMap){
Set<Id> acctIds = new Set<Id>();
Set<Id> opptyIds = new Set<Id>();
Map<Id, Id> contactIdAcctIdMap = new Map<Id, Id>();
List<Id> contactIds = new List<Id>();
for(Task t : newTaskTriggerMap.values()){
if(t.whoId != NULL){
contactIds.add(t.whoId);
}
}
for(Contact c : [SELECT Id, AccountId FROM Contact WHERE id IN :contactIds]){
contactIdAcctIdMap.put(c.Id, c.AccountId);
}
//loop through tasks and put account/oppty id's into sets
for(Task t : newTaskTriggerMap.values()){
if(t.WhatId == NULL && String.valueOf(t.WhoId).left(3) == '003'){
acctIds.add(contactIdAcctIdMap.get(t.whoId));
} else if(t.whatId != NULL && String.valueOf(t.WhatId).left(3) == '001'){
acctIds.add(t.AccountId);
} else if(t.whatId != NULL && String.valueof(t.WhatId).left(3) == '006'){
opptyIds.add(t.whatId);
}
}
List<Account> acctsToUpdate = new List<Account>();
//execute account update logic
if(!acctIds.isEmpty()){
List<Account> accts = [SELECT id, Number_of_Scheduled_Activities__c,
Number_of_Completed_Activities__c, Next_Activity_Date__c,
Last_Completed_Activity_Date__c, Next_Activity_Assigned_To__c
FROM Account WHERE Id IN :acctIds];
List<Task> acctTasks = [SELECT id, ActivityDate, OwnerId, IsClosed, AccountId, WhatId, RecordTypeId
FROM Task WHERE AccountId = :acctIds];
List<Opportunity> acctOpptys = [SELECT id, AccountId, IsClosed, CloseDate
FROM Opportunity WHERE AccountId IN :acctIds AND IsClosed = False
ORDER BY CloseDate ASC];
Map<Id, List<Task>> mapAcctidsTasks = new Map<Id, List<Task>>();
for(Task t : acctTasks){
if(!mapAcctIdsTasks.containsKey(t.AccountId)){
mapAcctIdsTasks.put(t.AccountId, new List<Task>());
}
mapAcctIdsTasks.get(t.AccountId).add(t);
}
Map<Id, List<Opportunity>> mapAcctIdOpptys = new Map<Id, List<Opportunity>>();
if(!acctOpptys.isEmpty()){
for(Opportunity o : acctOpptys){
if(!mapAcctIdOpptys.containsKey(o.AccountId)){
mapAcctIdOpptys.put(o.AccountId, new List<Opportunity>());
}
mapAcctIdOpptys.get(o.AccountId).add(o);
}
}
List<Task> tasksToUpdate = new List<Task>();
//loop through accounts and increment task counters tasks
for(Account a : accts){
Decimal numOpenTasks = 0;
Decimal numClosedTasks = 0;
Date nextScheduled;
Date lastCompleted = a.Last_Completed_Activity_Date__c;
Id nextAssigned = a.Next_Activity_Assigned_To__c;
if(!mapAcctIdOpptys.isEmpty()){
for(Task t : mapAcctIdsTasks.get(a.id)){
Task updatedTask = new Task(id=t.id);
//The following line is where I'm getting the null pointer errors
if(String.ValueOf(t.WhatId).left(3) == '003'){
updatedTask.whatId = mapAcctIdOpptys.get(t.WhatId)[0].Id;
tasksToUpdate.add(updatedTask);
}
if(!t.IsClosed){
numOpenTasks++;
if((nextScheduled == NULL || t.ActivityDate <= nextScheduled) &&
t.ActivityDate >= date.today()){
nextAssigned = t.OwnerId;
nextScheduled = t.ActivityDate;
}
}
if (t.IsClosed){
numClosedTasks++;
if(lastCompleted == NULL || t.ActivityDate >= lastCompleted){
lastCompleted = t.ActivityDate;
}
}
}
}
Account acctToUpdate = new Account(Id = a.id);
Boolean wasUpdated = false;
if(nextAssigned != a.Next_Activity_Assigned_To__c){
acctToUpdate.Next_Activity_Assigned_To__c = nextAssigned;
wasUpdated = true;
}
if(nextScheduled != a.Next_Activity_Date__c){
acctToUpdate.Next_Activity_Date__c = nextScheduled;
wasUpdated = true;
}
if(lastCompleted != a.Last_Completed_Activity_Date__c){
acctToUpdate.Last_Completed_Activity_Date__c = lastCompleted;
wasUpdated = true;
}
if(numClosedTasks != a.Number_of_Completed_Activities__c){
acctToUpdate.Number_of_Completed_Activities__c = numClosedTasks;
wasUpdated = true;
}
if(numOpenTasks != a.Number_of_Scheduled_Activities__c){
acctToUpdate.Number_of_Scheduled_Activities__c = numOpenTasks;
wasUpdated = true;
}
if(wasUpdated){
acctsToUpdate.add(acctToUpdate);
}
}
if(!acctsToUpdate.isEmpty()){
update acctsToUpdate;
}
if(!tasksToUpdate.isEmpty()){
update tasksToUpdate;
}
}