0

I wrote a method inside my triggerhandler class to avoid trigger recursion. But even after that , before update is not getting called.

I'm updating a datetime field(FieldA) from Process Builder. And with that value i'm checking the difference between the FieldA and another datetime field(FieldB) and updating the FieldA to null , if the difference is less than 5 days.

In trigger :

trigger CaseTrigger on Case(before update) {
    if(trigger.isBefore && trigger.isUpdate){  
      if(TriggerHandler.runOnce())        
        TriggerHandler.mymethod(trigger.new);
    }
} 

In triggerhandlerClass:

public class TriggerHandler {
  static boolean run = true;
    public static void mymethod(List<Case> newCases) {
      //some logic
    }
    public static boolean runOnce(){
      if(run){
       run=false;
       return true;
      }else{
        return run;
      }
    }
}
  • Typo? You used if(run), but the variable is called runOnce? – sfdcfox Mar 2 '18 at 13:44
  • Sorry , Yes. I edited now. – ram135868 Mar 2 '18 at 13:49
  • Okay, so what's the actual problem here? It doesn't run at all? It runs only once? – sfdcfox Mar 2 '18 at 13:51
  • This sounds like an order of execution issue. Update occurs->before trigger (sets runOnce)->after trigger->Process Builder->update->before trigger (does not run)->and so on. The trigger won't run in response to the PB updates in an update scenario. – David Reed Mar 2 '18 at 13:56
  • Yes @sfdcfox. It doesn't run at all. As David said , the execution order makes the issue. How can i come out of this – ram135868 Mar 2 '18 at 14:18
1

The "runOnce" pattern is typically used to avoid running the same trigger again on the same object. However, it has a number of limitations that make it a poor candidate for recursion blocking. For example, it will block the trigger from running at all in the event that there's more than 200 records in a list to be updated. It also prevents the trigger from running after workflow and process builder updates.

Usually, when we deal with recursion, we simply want to make sure that we don't end up in a scenario where trigger A calls trigger B that in turn calls trigger A. To prevent this scenario, we can use a temporary locking mechanism, like this:

public class CaseTriggerHelper {
  private static boolean isRunning = false;
  public static Boolean shouldRun() {
    return !isRunning && (isRunning = true);
  }
  public static void endRun() {
    isRunning = false;
  }
  public static void onBeforeUpdate(Case[] records) {
    //...
  }
}

The trick here is that we prevent infinite recursion only until the trigger context ends:

trigger CaseTrigger on Case (before update) {
  if(CaseTriggerHelper.shouldRun()) {
    CaseTriggerHelper.onBeforeUpdate(Trigger.new);
  }
  CaseTriggerHelper.endRun();
}

This design will stop any DML operations that may happen in onBeforeUpdate from going back in to the case trigger, but will allow multiple executions to run.

  • I wrote a blog about handling trigger recursion here: nebulaconsulting.co.uk/… Which offers some alternative thoughts. Although I didn't consider the exact method suggested by @sfdcfox, which is quite a neat variation, but could still have issues depending on the circumstances – Aidan Mar 2 '18 at 14:58
  • Here can we return two variables at a time ? Because I'm facing "Expression cannot be assigned" issue while saving this code – ram135868 Mar 2 '18 at 15:03
  • @ram135868 It only returns one value. The code had a couple of typos (pre-coffee!). I've updated this answer to something that'll compile. – sfdcfox Mar 2 '18 at 15:24
  • @Aidan Yes, I prefer to use the "do I need to do work?" method when possible, mentioned in your blog. Sometimes, though, you simply do need to stop recursion with some sort of static variable. This design is the minimum that I would use in my code, assuming it solved the problem. – sfdcfox Mar 2 '18 at 15:28
  • @sfdcfox , I incorporated this code and now my trigger is running 3 times and the update is not happening as expected – ram135868 Mar 2 '18 at 15:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.