How can I update a record in before trigger

  • I need to check if a record which is getting inserted has a duplicate. If there is one, then change a boolean field (Is_latest__c) to true in the inserted record and update the duplicate's field to false. I have created a before insert trigger, and in this trigger I check if a duplicate exists and change the Is_latest__c field of the inserted record to true. But when I try to update the old duplicate value in the trigger I am getting error that

    System.DmlException: Update failed. First exception on row 0 with id afdfd9000000hxuSAEAY; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, lastupdate: execution of BeforeUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id arfg45000000hxuSAEAY; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = artr9000000hxuSA) is currently in trigger lastupdate, therefore it cannot recursively update itself

    Is there any solution for this issue?

    My code:

    trigger lastupdate on Visit__c(before insert, before update) {
        if(Trigger.isBefore) {
            visitTriggerHandler vTH = new visitTriggerHandler();
            vTH.beforeInsertTrigger(Trigger.new);
        } 
    }
    
    public class visitTriggerHandler {
        public Set<String> contactFieldSet = new Set<String>();
        public Set<String> projectFieldSet = new Set<String>();
        public Set<String> surveyFieldSet = new Set<String>();
        public List<Visit__c> visitList = new List<Visit__c>();
        Map<Id, Visit__c> visitBeforeInsertMap = new Map<Id, Visit__c>();
    
        public void beforeInsertTrigger(Map<Id, Visit__c> visitBeforeInsertMaps, List<Visit__c> visitBeforeInsertList) {
            for(Visit__c visitToMap : visitBeforeInsertList) {
                visitBeforeInsertMap.put(visitToMap.Id, visitToMap);
            }
    
            for(Visit__c visit : visitBeforeInsertList) {
                contactFieldSet.add(visit.Contact__c);
                projectFieldSet.add(visit.Project_Group__c);
                surveyFieldSet.add(visit.Survey__c);
            }
    
            visitList = [SELECT Id FROM Visit__c
                         WHERE Survey__c IN :surveyFieldSet
                         AND Contact__r.Id IN :contactFieldSet
                         AND Project_Group__c IN :projectFieldSet
                         AND Is_latest__c = true];
    
            if(visitList.size() > 0) {
                for(Visit__c islastUpdate : visitBeforeInsertList) {
                    islastUpdate.Is_latest__c = true;
                }
            }
    
            //visitList.add(islastUpdate);
            visitBeforeInsertList = visitBeforeInsertMap.values();
            //update visitList;
        }
    }
    

    this can have different causes. Pls include your code so we can provide the right answer.

  • In a before update you don't need to explicitly call update on the records you want to modify. You're working on them before they go into the database, so you simply need to set the field values you want and that's it.

    trigger smithification on Contact (before insert, before update) {
       if(Trigger.isBefore)
          for(Contact c : Trigger.New)
             c.LastName = 'Smith';
    }
    

    The above trigger would mean all contacts currently being modified in the system have the last name 'Smith'.

    yes you are right. But here I need to update a old record when new duplicate recode is create it mean only on before insert. So that is way I am getting confused that same time when I insert a record I need to update to.

    If you're updating an old record, that will then fire the trigger again (as update). You'll want to use a static boolean or similar to prevent the trigger running a second time.

    yes but how can I update a old record in before insert. Because in before insert it is not allowing to update any record which is existing in data base.

  • First, by definition, all of the records inserted in the before insert trigger should be set to isLatest__c = true

    So, your problem is how to set the records with the same value of survey, contact.id, and project_group to isLatest__c = false

    I would break up this problem into two triggers - one before insert and one after insert (actually, I would use a trigger framework and just have different handlers for each trigger entry point but that is a longer discussion)

    The before trigger

    trigger isLatestUpdate on Visit__c (before insert) {
      for (Visit__c v : Trigger.new) 
         v.isLatest__c = true;  // implicitly sets the value of field in all members of trigger list to true
    }
    

    The after trigger

    trigger isNoLongerLatestUpdate on Visit__c (after insert) {
     Set<ID> contactIdSet = new Set<ID>();
     Set<String> surveySet = new Set<String>();
     Set<String> projGpSet = new Set<String> ();
    
     // Step 1 - build sets needed to query other Visits
     for (Visit__c v : Trigger.new)  {
        contactIdSet.add(v.contact__c);
        surveySet.add(v.survey__c);
        projGpSet.add(v.project_group__c);
     }
    
    // Step 2 - query for all other Visits (be sure not to query ourself) with matching survey/contact/proj gp
     List<Visit__c> noLongerLatestVUpdList = new List<Visit__c> ();
     for (Visit__c otherV : [select id, survey__c, contact__c, project_group__c 
                             from Visit__c 
                             where survey__c IN :surveySet and contact__c IN :contactSet and
                               project_group__c IN :projGpSet and id not IN :trigger.newMap.keySet()]) {
        otherV.isLatest__c = false;
        noLongerLatestVUpdList.add(otherV);
     }
    
    // Step 3 - update the no longer latest Visits
     try {
      update noLongerLatestVUpdList ;  // You could also do database.update(noLongerLatestVUpdList ,false) if you want to allow for partial successes in fixing up the old Visit__c
     }
     catch (DmlException e) { // do something useful here including, optionally, rolling back the transaction }
    

    Code was typed in -- might have compile errors

License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM