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

How to deal with triggers and merges

Before I begin, I wanted people to know that I've read the APEX documentation regarding Triggers and Merge Statements in the APEX Language Reference Guide located here:
and after reading it, I'm still a little confused.
Right now I have a custom object Lead_Status_History__c object that does some history tracking on the lead status every time the lead status changes. I've done it this way so that we can do reporting on the old and new values since Salesforce's reporting for lead history is limited (cannot set filters against old values and new values). The Lead_Status_History__c object has a lookup relationship to the Lead object (since you cannot make a master-detail relationship with leads, this was the only way).
In order to add/delete records to the Lead_Status_History__c object, I've written an APEX trigger that will deal with two events:
  • when the lead is updated (if the lead status has changed, then add a new entry to Lead_Status_History__c, I do not care about recording the initial insert)
  • when the lead is deleted (all associated Lead_Status_History__c objects related to the Lead are to be deleted)

The only other situation I do not know how to handle is when a Lead is being merged.

// trigger on lead (after delete) section
if ( Trigger.isDelete )
 // Trigger.old returns an array/list of old values (only available during deleting) 
 // Need to delete all instances of Lead Status History pertaining to this lead
// If this is a merge statement, how do you determine which leads are being merged? List<Lead_Status_History__c> LeadStatusHistoryDelete = [Select Id From Lead_Status_History__c Where Lead__c in :Trigger.oldMap.keySet()]; // Go throught each Lead_Status_History__c for( Lead_Status_History__c LeadStatusHistoryObject: LeadStatusHistoryDelete ) {
// Compare to each Lead Object? for ( Lead LeadObject: Trigger.old ) {
// How to determine which leads are being merged??
// Determine which leads are being merged then update the Lead_Status_History__c object with the Trigger.old.MasterRecordLeadId // Unsure about the condition statement or how to write it???
if ( LeadStatusHistoryObject.Lead__c == LeadObject.Id && LeadObject.Id != LeadObject.MasterRecordId )
    // Update the Lead_Status_History__c record to point to the new master Lead

// Delete the lead
} } } }

Does anyone have any APEX experience handling merges with triggers?

Please help!

Okay I figured it out.
Here's the behavior I have found in Salesforce when it comes to lookup objects when all related objects are deleted/merged.
For example:
I have a Lead standard object, and I have a Lead_Status_History_Object that has a lookup relationship to Lead (Lead_Status_History_Object__c.Lead__c field).
Upon deletion of the Lead, on the after delete trigger response:
- Lead_Status_History_Object__c.Lead__c becomes null
Upon merge, which fires a delete trigger response:
- Lead_Status_History_Object__c.Lead__c now has the new Lead.Id of the new master Lead.
So this whole time I didn't have to try to figure out anything, Salesforce takes care of that all for you when it comes to related objects and updating their related lookup fields.
The only thing I have to take care of upon deleting the lead is that when Lead_Status_History_Object__c.Lead__c becomes null, it basically becomes a phantom object (meaning not related to anything), in which they have to be deleted using APEX code (which gives it essentially the behavior of a child object in a master-detail relationship).
My delete section (which now works for both deleting and merging)
if ( Trigger.isDelete )
 // After a lead is deleted, all references to it via lookup fields will become null
 // If the lead is merged with another lead, the lead_status_history__c.lead__c field will be automatically updated. 
 // Need to delete all instances of Lead Status History that have null leads
 LeadStatusHistoryObjects = [Select Id, Lead__c From Lead_Status_History__c Where Lead__c = null];
 // Delete the lead status histories
  delete LeadStatusHistoryObjects;
  System.Debug( '\n\nLeadStatusHistoryObjects DELETE\n' );
  for ( Lead_Status_History__c LeadStatusHistoryObject: LeadStatusHistoryObjects ) System.Debug( '\n' + LeadStatusHistoryObject );
  System.Debug( '\n\nTrigger.old\n' + Trigger.old + '\n\n' );
 catch (DmlException de)
  for ( integer i = 0; i < de.getNumDml(); i++ )
   System.debug('LeadStatusHistoryTrigger Error Deleting Lead Status History Objects: ' + de.getDmlMessage(i));