2

I have a trigger for inserting a record. the trigger :

trigger myTrigger on Object__c(before insert) {

if (trigger.isBefore && trigger.isInsert) {
    myTriggerHandler.isBeforeInsert(trigger.new);
}

the apex class :

public class myTriggerHandler{

public static void isBeforeInsert(List<Object__c> lObj)
{
    myTriggerHandler.manageInsert(lObj);
}

public static void manageInsert(List<Object__c> lObj){

    System.debug('### lObj : ' + lObj); //null in logs
    Date date1;
    for(Object__ o : lObj){
        date1 = o.Obj2__r.StartDate__c; //I GOT AN ATTEMPT TO DEREFERENCE A NULL OBJECT HERE
    }
}

So in the log I got a null value for the id of the record in lObj (only one record is in this list for now)

I wonder how can I get the value of the object I'm inserting.

5
  • in before insert call id of the record is not available. Jun 21, 2017 at 9:27
  • record id is not available in before insert context, rest of the fields will be available.
    – Himanshu
    Jun 21, 2017 at 9:27
  • I edited my code sample with the operation I'm trying to do in the trigger : fill a date with the value of the record I'm trying to insert. But I got an error because the field seems to be null
    – dou
    Jun 21, 2017 at 9:34
  • relationship fields are also not available inside trigger. so query relationship object. store data in collection and then refer inside your code
    – Himanshu
    Jun 21, 2017 at 9:37
  • ok. But in the query, what kind of condition (where) can I put to get the right Object__c ?
    – dou
    Jun 21, 2017 at 9:40

4 Answers 4

3

Relationship fields are not available inside trigger. so query relationship object. store data in collection and then refer inside your code.

Here is sample code which will work for you.

public class myTriggerHandler{

public static void isBeforeInsert(List<Object__c> lObj)
{
    myTriggerHandler.manageInsert(lObj);
}

public static void manageInsert(List<Object__c> lObj){

    set<id> setlookup = new set<id>();
    for(Object__ o : lObj){
        setlookup.add(o.Obj2__c);
    }

    //query data from object 2 as relationship data is not available inside trigger.
    Map<id,Obj2__c> maplookupObject =  new Map<id,Obj2__c>([select id,StartDate__c from obj2__c where id in : setlookup]); // Edited

    System.debug('### lObj : ' + lObj); //null in logs
    Date date1;
    for(Object__ o : lObj){
        //access data here from map collection.
        date1 = maplookupObject.get(o.Obj2__c).StartDate__c;
    }
}
2

In SFDC you have two different moments in the trigger in which you can access the records: before and after.

The before event is when the record has not yet been inserted in the DB, therefore it has not been assigned an Id (given that it is an insert) and the changes have not been commited. On the other hand, the after event is when the record has been inserted and all the changes have been commited.

The big difference between both is that in the before events you can modify the records' fields at will and those changes will be persisted, while on the after, you can't change the records' field values.

Nonetheless, getting back to your code, which doesn't have much to do with the question, as I understand, you are trying to access a related record's field, not the trigger's record. To be able to access a related record's fields you need to query for its data before. You can try something like this:

public static void manageInsert(Object_A__c[] triggerRecords) {
    Set<Id> triggerRecordIds = new Set<Id>();
    for(Object_A__c obj : triggerRecords) {
        triggerRecordIds.add(obj.Id);
    }

    Map<Id, Object_B__c> relatedObjects = new Map<Id, Object_B__c>([SELECT Id FROM Object_B__c WHERE Id IN :triggerRecordIds]);

    for(Object_A__c obj : triggerRecords) {
        date1 = relatedObjects.get(obj.B_Lookup__c).StartDate__c;
    }
}

Still, take into account that for that to work you need to be in the AFTER trigger, which is when Object_A__c will have an Id.

1
  • You would need to be in an after trigger context if you were trying to query Object_A__c like [SELECT Id, B_Lookup__r.StartDate__c FROM Object_A__c]. Performing the query on Object_B__c, however, can be done in a before insert context (in a trigger on Object_A__c) because the field we'd be gathering Ids from to filter the query is a lookup field on Object_A__c (which can be populated before insert) instead of the Id field of Object_A__c (which as you stated, isn't available until after insert).
    – Derek F
    Jun 21, 2017 at 13:51
1

First -

You will not get the ID in before insert, because logically it is not yet inserted in database so there is no ID available.

Second -

date1 = o.Obj2__r.StartDate__c;

You are getting null pointer error, its because the record you are inserting doesn't have the related values in Obj2 its null, so on null object you can't do . (dot) operation.

Hope you find this helpful.

0

The Id of the record is generated only when it is committed in the data base. So the before insert trigger doesn't contain the value of ID so it throws the null pointer.

As the record ID is not present the the related values are also null, hence it cannot perform date1 = o.Obj2__r.StartDate__c

You must log in to answer this question.

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