1

For some odd reason, the Trigger.new contains accounts that are null and when I save, an exception is raised:

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, AccountTrigger: execution of BeforeInsert
caused by: System.NullPointerException: Attempt to de-reference a null object
Class.AccountTriggerHandler.CreateAccounts: line 4, column 1
Trigger.AccountTrigger: line 4, column 1: []

Here is my code:

trigger AccountTrigger on Account (before insert) {
    if(Trigger.isInsert && Trigger.isBefore) {
        System.debug(Trigger.new); //The trigger.new is not null but the accounts in it are
        AccountTriggerHandler.CreateAccounts(Trigger.new);
    }
}

The class

public class AccountTriggerHandler {
    public static void CreateAccounts(List<Account> accounts) {
        for(Account acct : accounts) {
            if(acct.ShippingState.compareTo(acct.BillingState) != 0) {
                acct.ShippingState = acct.BillingState;
            }
        }
    }
}

The test class

@isTest
private class AccountTriggerTest {
static testMethod void testUpdateShippingState() {
    //Arrange
    List<Account> newAccounts = new List<Account>();
    for(integer i = 0; i < 200; i++) {
        Account acct = new Account(Name='Test Account' + i, BillingState='CA');
        newAccounts.add(acct);
    }

    //Act
    Test.startTest();
    insert newAccounts;
    Test.stopTest();
    //Assert
    List<Account> updatedAccounts = [SELECT Name, BillingState, ShippingState FROM Account WHERE BillingState = 'CA'];
    for(Account acct : updatedAccounts) {
        System.assertEquals('CA', acct.ShippingState, 'Whoops! The states are not the same!');
    }
}
}

When I deactivate the trigger, an account is inserted successfully. That is the odd part.

What is wrong with the trigger?

1 Answer 1

4

The problem is HERE:

if(acct.ShippingState.compareTo(acct.BillingState) != 0) {

In your tests you are setting the billing state so the shippingState is Null.

compartTo throws DNO error when the operating string is null.

Check for null first:

if(acct.ShippingState == null || ( acct.BillingState != null && acct.ShippingState.compareTo(acct.BillingState) != 0)) {

if you do not need a lexicographical comparison simply use

acct.ShippingState != acct.BillingState;
5
  • Aye... A really bad error on my part.
    – akcorp2003
    Dec 27, 2016 at 19:13
  • Beat me to the punch
    – Derek F
    Dec 27, 2016 at 19:14
  • Yea, they really should handle nulls in that method but have not thought through the implementation of it to know how problematic it would be.
    – Eric
    Dec 27, 2016 at 19:14
  • This online solution developer.salesforce.com/forums/?id=906F0000000DCwCIAW has the logic as acct.BillingState != acct.ShippingState. Is there an advantage to that that there won't be a null check?
    – akcorp2003
    Dec 27, 2016 at 19:16
  • 1
    @akcorp2003 - it is much easier to implement. The compareTo is two strings lexicographically, based on the Unicode value of each character in the Strings and is a bit different then !=. Since you were using it I thought you needed that method. I would just go with !=. Updated answer accordingly
    – Eric
    Dec 27, 2016 at 19:18

You must log in to answer this question.

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