[SalesForce] Event parent relationship fields are null in trigger

I am populating a junction object on from Events and want to capture info from the Event but getting the Account from Account field pulls null. Same who the name via the Who. But if I query the Event record, the AccountId field is populated.
And of course, the code compiles properly. Can someone explain how to grab this related info?

trigger TripMeetingFromMeeting on Event (after insert, after update) {

    Set<id>EventId = new Set <ID>();
    List <Trip_Meeting__c> TMS = new List <trip_meeting__c>();

    for (Event E:trigger.new){
        if (e.Business_Trip__c!=null){
            TMS.add(new Trip_Meeting__c(Meeting__c =e.id, Business_trip__c=e.Business_Trip__c,
                                        Meeting_Date__c=e.ActivityDate, Meeting_subject__c=e.Subject,
                                       TripNameDELETE__c=e.Business_Trip__r.name,
                                        mWhatID__c=e.Whatid,
                                       Meeting_Company__c=e.Account.name,
                                       Meeting_Name__c=e.Who.name)
                                        );

        }
    }
    system.debug('TMS!!!============================'+TMS);
     Database.insert(tms, false);

}

Best Answer

This problem has a very simple solution, but first we need to understand the reason. You are using trigger context variables in iteration and trigger context variables i.e. trigger.new, trigger.old etc. do not query value of relationship field. So you can access e.AccountId, e.WhoId but not e.Account.Name or e.Who.Name. This is applicable to all triggers not just code that you have written.

To solve this problem you have two options:

  1. If you are in a after trigger, which you are in current situation you can write a query on your base object(Event) and query all fields that you need including relationship fields. so your code will be something like this:

    trigger TripMeetingFromMeeting on Event (after insert, after update) 
    {
        Set<id>EventId = new Set <ID>();
        List<Trip_Meeting__c> TMS = new List <trip_meeting__c>();
        List<Event> events = [Select Id, Business_Trip__c, ActivityDate, Subject, Business_Trip__r.name, e.Whatid, Account.Name, Who.Name From Event Where Id in : trigger.new];
        for (Event E: events){
            if (e.Business_Trip__c!=null){
                TMS.add(new Trip_Meeting__c(Meeting__c =e.id, Business_trip__c=e.Business_Trip__c,
                                    Meeting_Date__c=e.ActivityDate, Meeting_subject__c=e.Subject,
                                   TripNameDELETE__c=e.Business_Trip__r.name,
                                    mWhatID__c=e.Whatid,
                                   Meeting_Company__c=e.Account.name,
                                   Meeting_Name__c=e.Who.name)
                                    );
    
            }
        }
        system.debug('TMS!!!============================'+TMS);
        Database.insert(tms, false);
    }
    
  2. If you are in a before trigger, you need to process in three step, pre-process, query, post-process.

(a) Pre-Process - Build a set of Id for each related object that you want to access e.g. Account, User etc.

(b) Query - Write a query for each object and assign result to Map, where sobject should be your real object e.g. Account, User etc.

Map<Id, Account> accountMap = new Map<Id, Account>([Select Id, Name From Account Where Id in: accountIds]);

(c) Post-Process - In this step you iterate on trigger context variables and when it comes to access related object field you located that object from Map created in query step and access related field.

account.get(e.AccountId).Name;
Related Topic