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
MarkLevyMarkLevy 

APEX: Lead Insertion Trigger Duplicate Prevention: Don't roll back, instead merge/update?

I'm having a difficult time finding the answer to this question.

I coded up a before insert trigger that checks both the insertion set (all leads being currently inserted) as well as existing Leads+Contacts to see if the leads trying to be inserted already exist or are duplicated in the insertion set. The check is a cross-check on their email or alt-email for the insertion set itself, Leads, and Contacts.

I prevent the insertion of duplicate leads by adding an error when a duplicate is found (either in the insertion set, or already existing Lead/Contact in Salesforce), but doing this unfortunately rolls back the insert preventing that lead from being inserted and trying to insert again without that lead (as Salesforce does). This does not work for our purposes because ultimately if 2 leads insert at the same time (in the same insertion set) from our web insert they should merge into 1, not simply stop the second insert.

Instead of removing the duplicated lead from being inserted entirely, in cases where the existing Lead/Contact can be updated, or 2 leads are being inserted in this insertion set that are duplicated and can be merged I would like to update / merge the Leads, but I can't do that if it rolls back the insertion of all leads when I error the insert of 1 lead.

In short:

How can I prevent insertion of a single Lead in my insertion set without it rolling back and restarting the trigger (removing the lead from the insertion set and running the insert again) so that in the trigger itself I can either A: merge the lead with the other lead in the insertion set which is a duplicate, or B: update the existing Lead / contact with the new information.

Right now I'm thinking that this isn't possible and instead I should allow the lead to insert but set some sort of flag on it that says "Duplicate of LEAD_ID / CONTACT_ID" and then run a trigger after insert that merges the duplicated lead with the existing/duplicated-in-set lead/contact. Would that work? Is there a cleaner way of doing this? What am I not thinking about / should I keep in mind with this insertion logic?

Any assistance here is much appreciated. Thanks!
Best Answer chosen by MarkLevy
MarkLevyMarkLevy
The answer to this is that there is no way to prevent a lead from inserting in the 'before insert' trigger unless you error it thus rolling back to Salesforce trying to insert the lead set again without the lead that errored out. The only thing you can do is try to clean things up / merge after insert which is very dirty and I never got it to work properly.

All Answers

DixitDixit
Make another set for your set, make all the validations you need and go with 2 resultant sets.

set<lead> yourinitialset = (whateveryouhavehere)
set<lead> leadsInsert = new set<lead>();
set<lead> leadsFailed = new set<lead>();

for  checking 2 in the same set duplicated (far as i know sets don't admit dupplicates by themselves), iterate the "leadsinsert" set when running trought your initial set. 

for(lead ld : yourinitialset)
if(leadsinsert.size() == 0){
   leadsinsert.add(ld);
}else{
  for(lead lead : leadsinert){
   if(lead.email == ld.email){
      /* merge the fields */
    } else {
      /* check your leads and add to your insert set or to your "fail" set */  
    }
  }
}


if(leadsinsert.size() > 0){
 insert leadsinsert;
}


something like that :D 
try to adapt it to your case and sorry for just write it right here without testing.
MarkLevyMarkLevy
I'm running a "before insert" trigger. The leads are going to insert if I don't do anything, I don't code that part, it's already happening. The problem is that if I prevent 1 lead from inserting it rolls back all changes, removes the lead from trying to insert entirely, and starts over again preventing me from running any additional logic involving the duplicate.
Lumina SoftwareLumina Software
query your leads before insert, if there is 1, merge the fields and update, if the list size == 0, insert the lead.
MarkLevyMarkLevy
I'm sorry but the last post just doesn't make any sense at all in this context.
DixitDixit
I'm running a "before insert" trigger. 
-Great, so you can check if there is another Lead created already. 

 The leads are going to insert if I don't do anything,
-Yep

 I don't code that part, it's already happening.
-You can code the changes for doing the new validations? 

The problem is that if I prevent 1 lead from inserting it rolls back all changes
-Don't throw an error, just add the lead to a "failed list" (like List<lead> FailedInsertion = new List<Lead>(); )  and handle the elements on the list.

And starts over again preventing me from running any additional logic involving the duplicate.
-This should be fixed with the above point. 

I'm sorry but the last post just doesn't make any sense at all in this context.
-It does, before you insert your lead, query leads that has the same "X" field that your new one has. But we can't know if would work for you because you haven't post your code or part of it. 
 
MarkLevyMarkLevy
I don't understand, how does adding a lead to a failed list stop it from being inserted as a duplicate? Why would I add leads to an insertion list and insert them inside my "before insert" trigger when they are about to be inserted anyway? If I insert a lead "before insert" won't it then just insert again because it's about to be inserted anyway? What exactly does "handling the elements" on my failed list entail? I'm trying to get a straight answer to the questions I originally posed but I'm instead getting these vague "easy solutions" that I've already experimented with and don't work.
DixitDixit
Oh I see, sorry for not reading your mind. 
Maybe you can try this: https://developer.salesforce.com/page/Apex_Day_Lab_Exercises#Exercise_2%3aLead_duplicate_prevention
If that doesn't help you, I don't know what more to tell you. 

Good Luck. 
MarkLevyMarkLevy
The answer to this is that there is no way to prevent a lead from inserting in the 'before insert' trigger unless you error it thus rolling back to Salesforce trying to insert the lead set again without the lead that errored out. The only thing you can do is try to clean things up / merge after insert which is very dirty and I never got it to work properly.
This was selected as the best answer