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
Sunil NandipatiSunil Nandipati 

contact merge custom code to retain loosing record's id


When i merge a record, i want to store the Id of the loosing/deleted record on the Merged/Winning record.

So I came across this documentation
https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_merge_statements.htm

The following is the order of events when a merge occurs:

1.  The before delete trigger fires.
2.  The system deletes the necessary records due to the merge, assigns new parent records to the child records, and sets the MasterRecordId field on the deleted records.
3.  The after delete trigger fires.
4.  The system does the specific updates required for the master record. Normal update triggers apply.

-----------------------------------------------------------------------------------------------------------------------------------------

I created a custom field (text) on Contact and tried to put a after delete trigger like this

trigger RestoreMergedRecordInformation_Contact on Contact (after delete)
{
   
    Map<Id,String> mapMergeContacts = New Map<Id,String>();
    for(Contact delCon : Trigger.Old)
    {
        String oldString = mapMergeContacts.get(delCon.MasterRecordId);
        if(oldString != NULL)
        {
            oldString = oldString + String.valueOf(delCon.Id) + ';';
            mapMergeContacts.put(delCon.MasterRecordId,oldString);
        }
        else
        {
            mapMergeContacts.put(delCon.MasterRecordId,String.valueOf(delCon.Id) + ';');
        }
    }
   
    Set<Id> masterContactSet = New Set<Id>();
    masterContactSet = mapMergeContacts.keySet();
   
    List<Contact> masterContacts = [Select Id, Merged_Contacts__c from Contact Where Id in :masterContactSet];
    for(Contact thisCon : masterContacts)
    {
        thisCon.Merged_Contacts__c = mapMergeContacts.get(thisCon.Id);
        System.Debug('Id is - ' + thisCon.Id);
        System.Debug('Merged Contacts ' + mapMergeContacts.get(thisCon.Id));
    }
   
    update masterContacts;
}

Now I see I am getting an error since the winning record is being update ... error reads
"Apex trigger RestoreMergedRecordInformation_Contact caused an unexpected exception, contact your administrator: RestoreMergedRecordInformation_Contact: execution of AfterDelete caused by: System.DmlException: Update failed. First exception on row 0 with id 003xxxxxxxxxxxx; first error: SELF_REFERENCE_FROM_TRIGGER, Object 003xxxxxxxxxx is currently in a merge operation, therefore a trigger can not update it.: []: Trigger.RestoreMergedRecordInformation_Contact: line 56, column 1"

Experts, can you suggest if the trigger is being put on a wrong event (after delete).
Any suggestions?
ShashankShashank (Salesforce Developers) 
Try adding the "after update" event to the trigger and splitting the trigger into 2 parts, i.e., trigger.isdelete and trigger.isupdate.

Get the masterrecordIDs in the trigger.isdelete part and perform the dml update in the trigger.isupdate part.
Sunil NandipatiSunil Nandipati
Thanks for the response Shashank.  For now I put the update part in a future call.
However I want to get rid of the future thing due to shrewd governor limits for that process.

Tell me this,
So would I be able to access the all the deleted records (may be not in the recycle bin when massdelete happens and deleted records are more than the limits that can fit in the recycle) in the after update?

I am gonna try this meanwhile.
ShashankShashank (Salesforce Developers) 
Even after the delete, within the trigger context, you will still have read access to the deleted records by using "trigger.old".

As per the recycle bin question, if the recycle bin is full and you are performing a mass delete, the oldest records will be deleted first from the recycle bin and these newly deleted records should be available in the recycle bin, according to this article: https://help.salesforce.com/HTViewHelpDoc?id=home_delete.htm&language=en_US
Sunil NandipatiSunil Nandipati
Nope.  Its not working.  Looks like I cannot access the deleted records in an after update trigger.
I tried these with no luck

Trigger start (after update)
Trigger.ISdelete -> Print something 1
Trigger.Isupdate -> Print something 2
Trigger end

And it never printed 1.

I even tried printing something inside Trigger.Old loop, i cannot access the deleted records.


Thanks Shashank, I guess I will keep the future methods for now.