function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
singledotsingledot 

Using reference fields in APEX...how to initially query?

Hi. I'm looking to assign an Event.Location to a particular lookup relationship field from an object: 

 

 

trigger createPreCheckOutEvent on Set_Up_Transition__c (after insert, after update)
{
    Event[] eventList = new Event[]{};
    
    for (Set_Up_Transition__c suObj:Trigger.new){   
    
    if(suObj.Pre_Check_Out_Communication_2__c != null){
         
        Event evtobj = new Event();
        evtobj.OwnerId = suObj.Pre_Check_Out_Communication_2__c;
        evtobj.Subject = 'Pre Check Out Communication';
        evtobj.DurationInMinutes = 60;
        evtobj.StartDateTime = suObj.Pre_Check_Out_Communication_Time__c;
        evtobj.Location = suObj.Property_Address__r.Name;
        eventList.add(evtObj);
        }
       
    }
    
    insert eventList;
}

 

 

 

 

Basically, I'm new and discovering that the reference field I'm defining (suObj.Property_Address__r.Name) will be null unless I explicitly query for fields on the related record on my custom object (here, the Property_Address__r is in reference to the object Property__c). I'm completely at a loss for how to do this. Any help would be appreciated. Thanks

Best Answer chosen by Admin (Salesforce Developers) 
sfdcfoxsfdcfox

You'll need to use a pattern I often refer to as the Aggregate-Query-Update pattern (AQU).

 

Here's how we'd use AQU in your case:

 

trigger createPreCheckoutEvent on Set_Up_Transition__c (after insert, after update) {
    Event[] eventLIst = new Event[0];
    Map<Id,Property_Address__c> addresses = new Map<Id,Property_Address__c>();

// Aggregate
    for(Set_Up_Transition__c suObj:Trigger.new) {
        if(suObj.Pre_Check_Out_Communication_2__c != null) {
            addresses.put(suObj.Property_Address__c,null);
        }
    }
// Query
    addresses.remove(null);
    addresses.putAll([SELECT Id,Name FROM Property_Address__c WHERE Id IN :addresses.keySet()]);

// Update
    for(Set_Up_Transition__c suOBj:Trigger.new) {
        if(suObj.Pre_Check_Out_Communication_2__c != null) {
            eventList.add(
                new Event(
                   OwnerId = suObj.Pre_Check_Out_Communication_2__c,
                   Subject = 'Pre Check Out Communication',
                   DurationInMinutes = 60,
                   StartDateTime = suObj.Pre_Check_Out_Communication_Time__c,
                   Location = addresses.containsKey(suObj.Property_Address__c)?addresses.get(suObj.Property_Address__c).Name:''));
        }
    }
    insert eventList;
}

Don't get hung up on the ternary operator ( condition ? true : false ), I use those for simple assignments when there might be a condition. We need to check to make sure that there is an actual address before we try to reference it, or we'll get a null pointer exception.

 

Also, I didn't know if the related object was actually a Property_Address__c object, or whatever it was called, so you may need to adjust the code.

All Answers

sfdcfoxsfdcfox

You'll need to use a pattern I often refer to as the Aggregate-Query-Update pattern (AQU).

 

Here's how we'd use AQU in your case:

 

trigger createPreCheckoutEvent on Set_Up_Transition__c (after insert, after update) {
    Event[] eventLIst = new Event[0];
    Map<Id,Property_Address__c> addresses = new Map<Id,Property_Address__c>();

// Aggregate
    for(Set_Up_Transition__c suObj:Trigger.new) {
        if(suObj.Pre_Check_Out_Communication_2__c != null) {
            addresses.put(suObj.Property_Address__c,null);
        }
    }
// Query
    addresses.remove(null);
    addresses.putAll([SELECT Id,Name FROM Property_Address__c WHERE Id IN :addresses.keySet()]);

// Update
    for(Set_Up_Transition__c suOBj:Trigger.new) {
        if(suObj.Pre_Check_Out_Communication_2__c != null) {
            eventList.add(
                new Event(
                   OwnerId = suObj.Pre_Check_Out_Communication_2__c,
                   Subject = 'Pre Check Out Communication',
                   DurationInMinutes = 60,
                   StartDateTime = suObj.Pre_Check_Out_Communication_Time__c,
                   Location = addresses.containsKey(suObj.Property_Address__c)?addresses.get(suObj.Property_Address__c).Name:''));
        }
    }
    insert eventList;
}

Don't get hung up on the ternary operator ( condition ? true : false ), I use those for simple assignments when there might be a condition. We need to check to make sure that there is an actual address before we try to reference it, or we'll get a null pointer exception.

 

Also, I didn't know if the related object was actually a Property_Address__c object, or whatever it was called, so you may need to adjust the code.

This was selected as the best answer
singledotsingledot

This is so incredibly helpful...so new to all of this and scouring the books and boards has been frustrating.

I will be studying this.

Again. Thank you.