+ Start a Discussion
alexjalexj 

cannot operate on trigger.new or trigger.old

Hi,

I try to create an trigger which verify before the insert of lead if there has already a lead with the same mail. It is the case, I update the "old" lead and I delete the lead which would be created.

 

I have an error when I try to delete :

SearchDoubleAndFusion: execution of BeforeInsert caused by: System.SObjectException: DML statment cannot operate on trigger.new or trigger.old: Trigger.SearchDoubleAndFusion: line 48, column 1

How can I delete this lead ?

 

trigger SearchDoubleAndFusion on Lead (before insert, before update) 
{
    if(checkRecursive.runOnce())
        {
        Set<String> leadmail = new Set<String>();// liste des nouveaux id
        List<Lead> updatedLead = new List<Lead>();
        List<Lead> deletedLead = new List<Lead>();
        for (Lead l : trigger.new)// ajout des nouveaux id
        {
            leadmail .add(l.Adresse_mail__c);
            System.debug(l.Adresse_mail__c);
        }
        
        List<Lead> leads = [SELECT Id, Salutation, FirstName , Adresse_mail__c, LastName, Num_ro_piste__c from Lead /*where id in: leadId*/];
        
        for (Lead lnew : trigger.new)
        {
            for (Lead ld : leads)
            {
                if(ld.Id == lnew.Id)
                {
                    System.debug('Id egal'+ ' '+ld.Id+ ' '+lnew.Id);
                }
                else if(ld.Adresse_mail__c == lnew.Adresse_mail__c)
                {
                    System.debug('mail egal'+ ld.Adresse_mail__c+ ' '+ld.Id+ ' '+lnew.Id);
                                    
                    if(ld.Salutation == null){ld.Salutation = lnew.Salutation;}
                    if(ld.FirstName == null){ld.FirstName = lnew.FirstName;}
                    if(ld.LastName == null){ld.LastName = lnew.LastName;}
                    if(ld.Num_ro_piste__c == 0 || ld.Num_ro_piste__c ==null ){ld.Num_ro_piste__c = lnew.Num_ro_piste__c;}
                    if(ld.Adresse_mail__c == null){ld.Adresse_mail__c = lnew.Adresse_mail__c;}
                    if(ld.LeadSource == null){ld.LeadSource = lnew.LeadSource;}
                    if(ld.Client__c == null){ld.Client__c = lnew.Client__c;}
                    if(ld.Origine_connaissance_Kiwatch__c == null){ld.Origine_connaissance_Kiwatch__c = lnew.Origine_connaissance_Kiwatch__c;}
       
                    updatedLead.add(ld);
                    deletedLead.add(lnew);
                }
            }
        }
        if(updatedLead.size()>0){
            System.debug('mise à jour');
            update updatedLead;
        }
        if(deletedLead.size()>0){
            System.debug('mise à jour');
            delete deletedLead;
        }
    }
}

 

Best Answer chosen by Admin (Salesforce Developers) 
Jerun JoseJerun Jose

I am pretty sure Apex does not allow you to delete the triggering records through the trigger itself.

 

You could use a @future method and pass it the IDs of the records to be deleted. The future method will be executed shortly after the trigger and so, would let the trigger complete its execution and then proceed in its operation.

 

So in this case, once your trigger completes the operation, the future method can go delete the records marked for deletion.

All Answers

ministe_2003ministe_2003

This is because you're trying to delete the record that the trigger is currently processing.  You'll be able to do it by changing the firing criteria to after insert and after update.

alexjalexj

I have the same error when I change before by after : 

 SearchDoubleAndFusion: execution of AfterInsert caused by: System.SObjectException: DML statment cannot operate on trigger.new or trigger.old: Trigger.SearchDoubleAndFusion: line 48, column 1

alexjalexj

I have try to add message error but the problem is that the update isn't realized.

    if(updatedLead.size()>0){
            System.debug('mise à jour');
            update updatedLead;
        }
        for (Lead l : deletedLead){
         l.addError ('The lead already exists and has been updated');
        }

 However I see in debug that I enter in my first if

Jerun JoseJerun Jose

I am pretty sure Apex does not allow you to delete the triggering records through the trigger itself.

 

You could use a @future method and pass it the IDs of the records to be deleted. The future method will be executed shortly after the trigger and so, would let the trigger complete its execution and then proceed in its operation.

 

So in this case, once your trigger completes the operation, the future method can go delete the records marked for deletion.

This was selected as the best answer
alexjalexj

It's work. Thank you