[SalesForce] How to 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;
    }
}

Best 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'.