How to before update trigger Salesforce?
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 SetcontactFieldSet = new Set public Set(); projectFieldSet = new Set public Set(); surveyFieldSet = new Set public List(); visitList = new List Map(); visitBeforeInsertMap = new Map ();
public void beforeInsertTrigger(MapvisitBeforeInsertMaps, List for(Visit__c visitToMap : visitBeforeInsertList) {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;
}
}
For before update trigger Salesforce -
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 contactIdSet = new Set();
Set surveySet = new Set();
Set projGpSet = new Set ();
// 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 yourself) with matching survey/contact/proj gp
List noLongerLatestVUpdList = new List ();
for (Visit__c otherV : [select id, survey__c, contact__c, project_group__c
from Visit__c
where survey__c IN urveySet and contact__c IN :contactSet and
project_group__c IN rojGpSet 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