How to before update trigger Salesforce?

1.5K    Asked by EllaClarkson in Salesforce , Asked on May 4, 2023

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 contactFieldSet = new Set();
    public Set projectFieldSet = new Set();
    public Set surveyFieldSet = new Set();
    public List visitList = new List();
    Map visitBeforeInsertMap = new Map();
    public void beforeInsertTrigger(Map visitBeforeInsertMaps, List 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;
    }
}
Answered by Ella Clarkson

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


Your Answer

Answer (1)

In Salesforce, you can create a Before Update trigger to execute logic before records are updated. Here's a general outline of how you can create a Before Update trigger:

  1. Navigate to Setup: Log in to your Salesforce org and navigate to the Setup menu.
  2. Open Developer Console: In the Setup menu, search for and open the Developer Console.
  3. Create a New Apex Trigger:

  • In the Developer Console, go to File > New > Apex Trigger.
  • Enter a name for your trigger and select the object for which you want to create the trigger (e.g., Account, Contact, Custom Object).
  • Click on the "Submit" button to create the new trigger file.

In Salesforce, you can create a Before Update trigger to execute logic before records are updated. Here's a general outline of how you can create a Before Update trigger:

Navigate to Setup: Log in to your Salesforce org and navigate to the Setup menu.

Open Developer Console: In the Setup menu, search for and open the Developer Console.

Create a New Apex Trigger:

In the Developer Console, go to File > New > Apex Trigger.

Enter a name for your trigger and select the object for which you want to create the trigger (e.g., Account, Contact, Custom Object).

Click on the "Submit" button to create the new trigger file.

Write Trigger Logic:

In the newly created trigger file, you'll see a template with trigger keyword followed by your trigger's name.

Write your trigger logic within this trigger context. For a Before Update trigger, you would typically use the before update trigger context variable.

Example:

trigger MyObjectBeforeUpdate on MyObject__c (before update) {
    for (MyObject__c obj : Trigger.new) {
        // Your logic here
        // This logic will be executed before each record is updated
    }
}

Save and Activate the Trigger:

After writing your trigger logic, save the trigger file.

Once saved, click on the "Compile" button to ensure that your trigger compiles without errors.

After successful compilation, your trigger is ready to be activated.

Test the Trigger:

Before activating the trigger in a production environment, it's essential to test it thoroughly in a sandbox or developer org.

Create or update records that would invoke the trigger and verify that the trigger behaves as expected.

Deploy to Production:

If your trigger works as expected in the testing environment, you can deploy it to your production org using change sets or a deployment tool.

Activate the Trigger:

Once deployed to production, activate the trigger to make it functional.

Remember to follow Salesforce best practices when writing triggers, such as bulkifying your code to handle bulk data operations efficiently and avoiding unnecessary SOQL queries or DML statements inside loops.


6 Months

Interviews

Parent Categories