+ Start a Discussion
Wayne McMahonWayne McMahon 

I keep getting this error when trying to delete a record - DML statement cannot operate on trigger.new or trigger.old site:developer.salesforce.com

trigger updateLeadTest on Lead (before insert) {

     //create a map to hold emails/lead                          
    Map<String, Lead> leadMap = new Map<String, Lead>();
    Lead lead2 = new lead();

    for (Lead Lead : System.Trigger.new) {
        
        // Make sure we don't treat an email address that  
        // isn't changing during an update as a duplicate.  
        if ((Lead.Email != null) && (System.Trigger.isInsert || (Lead.Email != System.Trigger.oldMap.get(Lead.Id).Email))) {
        
            // Make sure another new Contact isn't also a duplicate  
    
            if (leadMap.containsKey(Lead.Email)) {
                Lead.Email.addError('Another new lead has the '+ 'same email address.');
            } else {
                leadMap.put(Lead.Email, Lead);
            }
       }
    }

    //put new emails into set
    for(Lead l:Trigger.new){
      if(l.email != null)leadMap.put(l.email,l);
    }

    list<lead> deleteList = new list<lead>();//these are only new records (b)
    list<lead> updateList = new list<lead>();//these are only existing records (a)
    
    // Using a single database query, find all the Contacts in  
    
    // the database that have the same email address as any  
    
    // of the Contacts being inserted or updated.  
    
    for (Lead lead : [SELECT Email, Phone, Company FROM Lead WHERE Email IN :leadMap.KeySet()]) {
        lead2 = leadMap.get(lead.Email);
        if(lead2.email != null && lead2.email == lead.email && lead2.Company == lead.Company){

          // newLead.Email.addError('A Lead with this email address already exists.');
          lead b = new lead();
          b = leadMap.get(lead.email);
             

          // if(lead2.Email == lead.Email){
            
               
              //lets update lead2 with some items from Lead
              //Always update the phone number from Lead if it is not null

              if(b.Phone != null)lead.Phone  = b.Phone;
                
              //update the email from b --> a ONLY if a is null and b is not, so not overwrite a
          
              //now, add a to the list to be updated with new values.
              updatelist.add(lead);
              
               [Select Id From Company__c Where Id IN :Trigger.new];
              //now, lets get rid of B
              deleteList.add(b);
            
         // }
       }else{
           
       }

  }
  if(deleteList.size() > 0){
      delete deleteList;
  }
  if(updatelist.size() > 0){
    update updateList;
 }
}

I am trying to update a lead if the email address already exists. This trigger updates the old record but I need to delete the newly created record and it gives me the 'DML statement cannot operate on trigger.new or trigger.old site:developer.salesforce.com' error.

Any ideas?

 
Wayne McMahonWayne McMahon
I ahve tried it with 
trigger updateLeadTest on Lead (after insert)

Still get same error
Aman PathakAman Pathak
I might be wrong about it but I think apex don't allow  us to delete the reords which triggered it  in the trigger itself. Please pass that list to  a @future method , so the trigger will run its course and then calls the future method which in turns deleted the inserted duplicate list shortly after the trigger ends.

Thanks,
Aman
Aman PathakAman Pathak
set<id> Ids of those leads, to the future method ,list won't work in future method
Wayne McMahonWayne McMahon
Thanks Aman for your answer.

Where do I create a future method? I'm new to Salesforce.
Aman PathakAman Pathak
create a new apex class  
public class leadtrhHandler {

  @future 
public static void LeadDelete(set<id> leadId)
{
    if(!leadId.isEmpty())
{
   delete leadId;
}
}
}
 declare a  set<id>  and addIds of the lead to be deleted to  like 
set<id> setleadTodelete = new set<id>(); // at the top may be
setleadTodelete.add(b.id);// add the ids of lead to be deleted

//call the future handler where you are checking the size of the delete list in that if block

//like

if(deletelist.size()>0)
{
 leadDelete(setleadTodelete);
}

 
call this in the trigger itself probably
 
Aman PathakAman Pathak
set<id> setleadTodelete = new set<id>(); // at the top may be
setleadTodelete.add(b.id);// add the ids of lead to be deleted

//call the future handler where you are checking the size of the delete list in that if block

//like

if(deletelist.size()>0)
{
 leadtrhHandler.leadDelete(setleadTodelete); // please this one ignore the previous one
}

a slight change please see to it, I forgot to write the class name in hurry.
Thanks,
Aman Pathak
Wayne McMahonWayne McMahon
Thanks so much for your help.

I have this solution nearly working. But the problem is the function is running 'before insert' and therefor the new lead that needs to be deleted doesn't have an id yet (id is set to null when I check). Do I need to set up another function for 'After Insert', pass the id and delete it in that function?