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
tvonemstertvonemster 

Attempt to de-reference a null object

HI all,

 

I've just spent the last four hours attempting to write and test my first trigger.  We have a custom object Health Check that has a Master-Detail relationship to Accounts.  We instantiate a new HC record ~3 months.  We want to copy the notes from the previous HC to the new one.  I have taken a clicks & code approach to this. I am looking for hope on my code, but if there is a better way to approach this whole effort, I'm certainly open.

 

On the Health Checks object, I have a "Date Conducted" field and a rich text field (I know, but my users insisted) called "Health Check Notes." I also have an Account__c field, which contains the parent Account's ID.

On Accounts, I have a "Last Health Check Conducted" field and a "Health Check Notes" field (also a RTF).

 

I have a WFR that fires when a new Health Check is created or edited.  If "Date Conducted" >= "Last Health Check Conducted" (also covers my users editing their notes after the call as issues are resolved), I copy the contents of the Health Check Notes field from the child Health Check object to the parent Account.  That's tested and working.

 

Next, when a new HC is created, I need to copy the contents from the parent Account into the new HC record.  Since WFR won't go parent->child, I did some research and wrote a trigger:

 

trigger populateHealthCheckNotes on Health_Check__c (after insert){
  
    Map<Id,Account> accounts = new Map<Id,Account>
    ([select ID, Health_Check_Notes__c from Account where Id IN :trigger.newMap.keySet()]);
  
    for(Health_Check__c hc : trigger.new){
         if(hc.Account__c != null){
         hc.Health_Check_Notes__c = accounts.get(hc.Account__c).Health_Check_Notes__c;    
          }
    }   
 
}

 

 

 

I wrote a Test Class to go with this:

@isTest 
private class testPopulateHealthCheckNotesTrigger {
  static testMethod void testNotePopulation()  {
    Account testAccount = new Account(Health_Check_Notes__c = 'Negotiating',Name = 'test Name');
    insert testAccount;
    Health_Check__c testHealthCheck = new Health_Check__c(Account__c = testAccount.ID);

Test.startTest();
insert testHealthCheck;
Test.stopTest();
system.assert(testHealthCheck.Health_Check_Notes__c == testAccount.Health_Check_Notes__c);
}

}

 

 

 

However, I'm getting this error:

 

Time Started 6/25/2013 11:52 AM Class testPopulateHealthCheckNotesTrigger Method Name testNotePopulation Pass/Fail Fail Error Message System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, populateHealthCheckNotes: execution of AfterInsert

caused by: System.NullPointerException: Attempt to de-reference a null object

Trigger.populateHealthCheckNotes: line 8, column 1: [] Stack Trace Class.testPopulateHealthCheckNotesTrigger.testNotePopulation: line 9, column 1

 

I'm pretty sure I'm doing something wrong and it has to do with grabbing the account ID and making sure I'm copying the right information, but I'm not sure where/how I'm going wrong exactly.  I need this to work, as I have a similar copy-and-paste exercise to do with two other fields, but trying to start small and stay on sure footing here.

 

All help greatly appreciated.

 

SLockardSLockard

You are getting that error because your map of accounts is actually empty because the trigger.newMap.keySet() is the set of the health_check__c ids, not their account__c field. To fix that, you need to loop through and get all of the account__c fields to query by. Also, because you are editing the health_check__c objects, you want to make the trigger execute before the insert.

Try this code, I hope it helps you!

 

trigger populateHealthCheckNotes on Health_Check__c (before insert)
{
  
    Map<Id,Account> accounts = new Map<Id,Account>();
  	Set<Id> accountIds = new Set<Id>();

    for(Health_Check__c hc : trigger.new)
    {
         if(hc.Account__c != null)
         {
         	accountIds.add(hc.Account__c);
         }
    }

    if (accountIds.size() > 0)
    {
	    accounts = [SELECT Id, Health_Check_Notes__c FROM Account WHERE Id IN: accountIds];

	    for (Health_Check__c hc: trigger.new)
	    {
	    	if (hc.Account__c != null)
	    	{
	    		hc.Health_Check_Notes__c = accounts.get(hc.Account__c).Health_Check_Notes__c;
	    	}
	    }
 	}
}

 

tvonemstertvonemster

Thank you! I see the changes you made and they make a lot of sense to me.

 

I'm getting a new compile error:

 

Error: Compile Error: Illegal assignment from LIST<Account> to MAP<Id,Account> at line 12 column 8

 

In the code, line 12 starts with "accounts =" from this snippet:

 if (accountIds.size() > 0) { 
       accounts = [SELECT Id, Health_Check_Notes__c FROM Account WHERE Id IN: accountIds]; 

 

How do I fix this?

 

Thank you!

 

 

gedeefgedeef

you have to change it to

accounts = new Map<Id,Account>([SELECT Id, Health_Check_Notes__c FROM Account WHERE Id IN: accountIds]);

 



and then you can change your first line to

Map<Id,Account> accounts;

 

Roger JreyesRoger Jreyes
did this algo help in health (https://www.memphisliposuction.com/photo-gallery/) system