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
econ242econ242 

BeforeInsert Trigger error

Hello,

I have created a trigger that updates a hidden field on an Account record that was needed in order to track changes on a seperate field that is a formula field. When the field value changes, the trigger runs and captures the previous value in the Account History. Below is my trigger code (in Sandbox) that works perfect:


trigger BusinessRatingChange on Account (before insert, before update)
{
    for(Account a:Trigger.new)
    {
        if(system.trigger.OldMap.get(a.Id).Business_Rating__c != system.trigger.NewMap.get(a.Id).Business_Rating__c)
        {
            a.Business_Rating_History__c = a.Business_Rating__c;
            }
            }
            }

However, when I attempt to create a NEW account, I get the below error that looks like is due to the "BeforeInsert" action on the trigger:


Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger BusinessRatingChange caused an unexpected exception, contact your administrator: BusinessRatingChange: execution of BeforeInsert caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.BusinessRatingChange: line 5, column 1


Does anyone have any insight as to how I can remedy this? Thanks so much in advance for your assistance!!!

Eric
Best Answer chosen by econ242
sbbsbb
I would make a simple change if all you want in this trigger is to save the previous value of Business_Rating__c field in Business_Rating_History__c field. Just make it a 'before update' trigger (remove the 'before insert' in the very first line).

If you are planning to add more logic that requires you to make it a before insert trigger as well, then this should work:

if (trigger.isUpdate){
    if(system.trigger.OldMap.get(a.Id).Business_Rating__c != system.trigger.NewMap.get(a.Id).Business_Rating__c)
    {
        a.Business_Rating_History__c = a.Business_Rating__c;
    }
}

All Answers

sbbsbb
OldMap is not available during insert. So you need to use
if (Trigger.isUpdate)
for code specific to update logic.

I would also revisit the trigger logic. If you are inserting a new record, you really don't need to check the 'old' value of a field -- all values are new.

econ242econ242
Makes complete sense what you're saying, but there could be an existing value there on an existing Account. I'm fairly new to triggers so i'm still learning. To allow NEW Accounts to get entered/created without this error, and to have this trigger fire when an existing Account is updated...where to I enter the "if (Trigger.isupdate)? Sorry I don't quite get understand triggers completely yet...but this was VERY helpful. One thing I did notice however, is that if I convert a Lead to an Account...there are no errors during conversion...only when I create from scratch...
sbbsbb
I would make a simple change if all you want in this trigger is to save the previous value of Business_Rating__c field in Business_Rating_History__c field. Just make it a 'before update' trigger (remove the 'before insert' in the very first line).

If you are planning to add more logic that requires you to make it a before insert trigger as well, then this should work:

if (trigger.isUpdate){
    if(system.trigger.OldMap.get(a.Id).Business_Rating__c != system.trigger.NewMap.get(a.Id).Business_Rating__c)
    {
        a.Business_Rating_History__c = a.Business_Rating__c;
    }
}

This was selected as the best answer
James LoghryJames Loghry
If there is no other logic involved other than setting Business_Rating_History, then I would consider using a Workflow Rule / Field Update.  That way, administrators can find and modify the logic easily and you don't have to write a unit test for the trigger. 

Also, below is another way of providing update checking in your trigger.  Behaves the same as sbb's excellent example, just more food for thought:

if(Trigger.oldMap == null || Trigger.OldMap.get(a.Id).Business_Rating__c !=  a.Business_Rating__c){
        a.Business_Rating_History__c = a.Business_Rating__c;
}


econ242econ242
Thank you sbb and James for your input...I used sbb's method and it is workinig like a charm...now I'll just need to figure out how to write the test class, lol!!!

Thank you both again...so very helpful!!!