+ Start a Discussion
bikla78bikla78 

Trigger - Dereference Null Object Exception

I am trying to create a trigger that prevents a user from deleting a contact record if contact.contact_type__c = 'Client'.  I keep getting this issue below. What is the null object they are referring to?

 

trigger ContactDeleteTrigger on Contact (before delete)
{
    

    if (Trigger.isDelete) {


        for (Contact c : Trigger.new) {
            if (c.contact_type__c != 'Client') {
                c.addError('You can\'t delete this record!');
            }
        }
    }
}
ContactDeleteTrigger: execution of BeforeDelete

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

Trigger.ContactDeleteTrigger: line 8, column 26
CaptainObviousCaptainObvious

Try this:

trigger ContactDeleteTrigger on Contact (before delete)
{
    if (Trigger.isDelete) {
        for (Contact c : Trigger.old) {
            if (c.contact_type__c == 'Client') {
                c.addError('You can\'t delete this record!');
            }
        }
    }
}

 

bikla78bikla78

Thanks it worked but 2 quesitons.

 

1. Why does having trigger.old matter?

 

2. How can I do this so the add error message shows up on the contact type field? Currently, it displays the message on a different page. I tried this code but it still shows add error message on a different page

 

trigger ContactDeleteTrigger on Contact (before delete)
{
    if (Trigger.isDelete) {
        for (Contact c : Trigger.old) {
            if (c.contact_type__c == 'Client') {
                c.contact_type__c.addError('You can\'t delete this record!');
            }
        }
    }
}

CaptainObviousCaptainObvious

1. trigger.new is not available in the before delete trigger event. See here.

 

2. Again, I dont think you can add the error to a specific field like that through a before delete trigger.

Message Edited by CaptainObvious on 04-02-2010 01:53 AM
bikla78bikla78

Thank you.

 

Last question: How do I write a test method to delete this contact.

CaptainObviousCaptainObvious

To write your test, you'll want to programatically re-create the trigger scenario.
For the bare minimum, you'll need a Contact with a Contact Type of 'Client', and an account to associate the contact with.

 

@isTest
private class deleteContacts_Test {

    static testMethod void deleteContact() { 
    
        //Create an Account
        Account A1 = new Account( Name = 'Test Account');
        insert A1;
        
        //Create a Contact, associating it with the above account
        Contact C1 = new Contact(
            FirstName='John',
            LastName='Smith',
            AccountId = A1.id,
            contact_type__c = 'Client'
        );
        insert C1;
        
	//Deleting the above contact causes the trigger to fire
        try { delete C1; } 

        catch (System.DMLException e) {
	//verify that you received the correct error message
            System.assert(e.getMessage().contains('first error: 
		FIELD_CUSTOM_VALIDATION_EXCEPTION, You can\'t delete this record!'),
		e.getMessage());     
        }
    }
}

 Note that the highlighted line should be on the same line, or you'll receive a line break error.

 

There's more to do!

  • Create another contact with a different contact type and delete it- then verify that you did not receive an error message. 
  • Create/delete contacts in bulk, and verify that the trigger works as designed.

For tips on testing Apex, read the Introduction to Apex Code Test Methods.

 

Edit: fixed a typo.

bikla78bikla78

Almost there but I am having issues. I succesfully deployed this test method in production and when I try to deploy the trigger and try to validate, 0 percent is passed since the error i get is the trigger add error message itself! How can i get past this?

 

"System.assert(e.getMessage().contains('first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, You can\'t delete this record!'),"

 

Class.deleteContacts_Test.deleteContact: line 35, column 13 External Entry point

 

 

@isTest
private class deleteContacts_Test
 {
    static testMethod void deleteContact() {
    
        //Create an Account
        Account A1 = new Account( Name = 'TestAccount', Type =  'Prospect', Industry = 'Banking', Physical_Street__c = 'Test Street',Physical_City__c = 'Los Angeles', Physical_State__c = 'CA', Physical_Zip_Postal_Code__c = '90017', Physical_Country__c = 'USA', Phone = '(888) 999-1234'  );
        insert A1;
        
        //Create a Contact, associating it with the above account
        Contact C1 = new Contact(
            FirstName='John',
            LastName='Smith',
            AccountId = A1.id,
            contact_type__c = 'Client',
            mailing_country__c = 'USA',
            mailing_street__c = 'Wilshire',
            mailing_state__c= 'CA',
            mailing_Postal_Code__c ='90017',
            mailing_city__c = 'LA',
            title = 'janitor',
            functional_area__c = 'Finance',
            title_level__c = 'VP',
            Direct_Mail_Status__c ='Do Not Send',
            leadsource = 'Direct Mail'          
            
     );
        insert C1;
        
    //Deleting the above contact causes the trigger to fire
        try { delete C1; }

        catch (System.DMLException e) {
    //verify that you received the correct error message
            System.assert(e.getMessage().contains('first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, You can\'t delete this record!'),
        e.getMessage());     
        }
    }
}

 

// This trigger ensures that client contacts are not deleted in Salesforce. This is a requirement to interface opportunity records into Oracle.
trigger ContactDeleteTrigger on Contact (before delete)
{
    if (Trigger.isDelete)
    {
        for (Contact c : Trigger.old)
        {
            if (c.contact_type__c == 'Client')
            {
                c.contact_type__c.addError('You can not delete a client contact. Please contact your administrator');
            }
        }
    }

 

}