0

I am very much new to sales force and I was trying out with trailhead module Apex & .Net Basics > Understand Execution Context.

while writing the code for when on case if Asset is linked with case then asset order must be reflect on case order (order is lookup with both case and asset here and asset is lookup with case)I faced an error like

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

Main Class

public with Sharing class CaseTriggerHandler{
    
    public static void CARE_Order_Update(List<Case> newCaseList)
        {
            Map<Id,Asset> assetMap;
            Set<Id> assetIds = new Set<Id>();
            for(case c : newCaseList )
            {
                if(c.AssetId != Null){
                        assetIds.add(c.AssetId);
                    }
                if(assetIds != null && !assetIds.IsEmpty()){
                    assetMap = new Map<Id,Asset>([select Id,OrderId__c from asset where id=:assetIds limit 1]);
                }                    
                c.CARE_Order__c=assetMap.get(c.AssetId).OrderId__c;
                
            }
        }
}

Trigger

    trigger CaseTrigger on Case (before insert,before update,after update, after insert) {
    if(trigger.isBefore && (trigger.isInsert || trigger.isUpdate)){
            CaseTriggerHandler.CARE_Order_Update(trigger.new);
    }

Test class

@isTest
public class CaseTriggerHandler_Test {
    Private static void CARE_Order_Update_Test()
        {   
        User u = SRVS_CreateTestDataFactory.createUser('System Administrator');
            system.runAs(u){
                Test.startTest();
                //create a test account
                Account acnt1234=SRVS_CreateTestDataFactory.createSingleAccountRecord();
                acnt1234.Industry='Fashion';
                acnt1234.Type='Customer';
                acnt1234.AccountNumber='12345670828';
                acnt1234.BUID__c='99901';
                insert acnt1234;
    //create a test order
    Order ordr1234 = SRVS_CreateTestDataFactory.createOrder(acnt1234.id);
            insert ordr1234;
    //create a test asset
                Asset ast1234=SRVS_CreateTestDataFactory.createSingleAsset(acnt1234.id);    
                ast1234.Name='Test Asset';
                ast1234.OrderId__c=ordr1234.id;
                insert ast1234;            
    //create test case records
                Case cs = new Case();
                cs.subject='Test Case';
                cs.CARE_Order__c=null;
                insert cs;
                cs.AssetId=ast1234.id;
                update cs;
                
                Test.stopTest();            
                system.assertEquals(ast1234.OrderId__c,cs.CARE_Order__c);
            }
        }
}
1
  • 1
    Given the line numbers in the stack trace, it'll help if you call out specifically which line you are encountering the error on. If it's c.CARE_Order__c = assetMap.get(c.AssetId).OrderId__c; then I'd add "this line [code here] is where the error is", outside of all the other code blocks, to your question.
    – Derek F
    Jun 16, 2022 at 16:32

1 Answer 1

2

This line here is the culprit:

c.CARE_Order__c=assetMap.get(c.AssetId).OrderId__c;

If AssetId is null, then the .OrderId__c throws a NullPointerException.

There's a larger issue here, though, and that is you are querying inside a loop. This may reach governor limits on large data loads (>100 records).

You should get the Asset Ids, then query them, and then perform any updates. I call this Aggregate-Query-Update pattern.

public with Sharing class CaseTriggerHandler{
    public static void CARE_Order_Update(List<Case> newCaseList) {
        Map<Id, Asset> assetMap = new Map<Id, Asset>();
        // Aggregate records we want to query
        for(Case record: newCaseList) {
            assetMap.put(record.AssetId, null);
        }
        assetMap.remove(null); // Ignore nulls
        // Query for related records
        assetMap.putAll([SELECT OrderId__c FROM Asset WHERE Id = :assetMap.keySet()]);
        // Update the cases with the new data
        for(Case record: newCaseList) {
            // ?. prevents NullPointerException below
            record.CARE_Order__c = assetMap.get(record.AssetId)?.OrderId__c;
        }
    }
}

You must log in to answer this question.

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