Is there any way to detect that a BEFORE_DELETE
trigger was caused by a merge
operation?
I need to manually reparent/fix/delete some related child records before they are reparented automatically by the merge operation.
But since MasterRecordId is only filled in in the AFTER_DELETE
trigger, when all related records are already reparented, there is no way to know if the related record belonged to the winning or losing record.
-
It really depends on the way you are merging the records. Are you using apex to merge these records? Do you have any custom duplicate catcher? How are you selecting the records before merging them? ... If you want to flag records as 'merged records' and them fire a Before Delete DML operation and execute some extra logic on those 'merged records', I think you need to code a solution for this.– Carlos NaranjoCommented Feb 27, 2020 at 12:17
-
I am talking about the standard "Merge Accounts" page (/merge/accmergewizard.jsp), I am not initiating the merge myself.– Gobius DolhainCommented Feb 27, 2020 at 12:21
-
If I recall correctly there's no way to do this. Also, no triggers will fire on the child objects, so you won't be able to hook into that. When I needed to do this, I had to make the changes retroactively in the after delete context.– user254875486Commented Feb 27, 2020 at 12:24
-
Don't think you can do this wit the standard SFDC functionality.– Carlos NaranjoCommented Feb 27, 2020 at 12:30
-
I know the reparented child triggers dont fire, that's the reason I try to reparent them manually.– Gobius DolhainCommented Feb 27, 2020 at 12:39
2 Answers
The solution is a split trigger. This needs a static variable for you to store the data in.
trigger handleMerge on X (before delete, after delete) {
if(Trigger.isBefore) {
TriggerHandlerForX.storeChildData(Trigger.old);
} else {
TriggerHandlerForX.processMerges(Trigger.old);
}
}
public class TriggerHandlerForX {
static sObject[] children;
public static void storeChildData(X[] parents) {
children = [select ... from children where parent in :parents];
}
public static void processMerges(X[] parents) {
for(X parent: parents) {
if(hasMasterId(parent)) {
handleOtherChanges(children);
}
}
}
}
This is obviously pseudo-code, but hopefully it demonstrates how to handle this. Let the automatic updates take care of themselves, but you can process the children in any special manner you need. Be aware that they'll still have the "old" Id values, even though they may have the new values in the database. We made the copy of the records before the database change happened.
I think that perhaps you can accomplish this by using a Boolean on the records that are possible to merge which I believe are: Lead, Contact, Account, Person Account.
Add a custom field, check box, to those objects.
Named: Merged?
When merging records you can tick that custom field. This way to can flag records that were merged. On triggers you need to look at the value of the custom field to execute further logics around these records.