4

I am trying to stop a cyclic situation between two triggers. Trigger B is the primary - it runs when an Opp is edited (to put some data on the ACCOUNT). Trigger A was written so that if the Account is edited or merged, it edit/saves each Opportunity afterward, causing a cleanup of the data on the Account (especially after merges).

Because A is fired by an edit on Account, and B touches the Account at the end of the process, A fires B fires A... etc...

I tried setting a hidden checkbox field and then unsetting it in an IF in Trigger A, but the record is LOCKED at the time so I cannot clear the checkbox (else this would solve my problem - first time, A fires B, which fires A but the set checkbox skips firing B then clears the checkbox - which in itself would ALSO PROBABLY be an issue, but I digress...).

So it was suggested that I create a Static copy of the Accounts being touched in Trigger A, and then when it fires "again", that list could be used to exclude them. I need help with this - I have no clue how to create a Static reference, especially with a "Map" set. :-(

Note the code below in Trigger A:

Account[] acctsInTriggerSet = new List<Account>();
Opportunity[] opptysToUpdate= new List<Opportunity>();

if( PiggybackTriggerManager.PBOppFromAccountCheck == true ){
    //Do nothing, the calculation is done
} else {

    for(Account a :Trigger.new){  
        acctsInTriggerSet.add(a);
    }

    For( Opportunity o : [SELECT id, Name
                          FROM Opportunity 
                          WHERE Accountid 
                          IN :acctsInTriggerSet] ) {
    // o.Name = o.Name; 
    opptysToUpdate.add(o); } 

    update opptysToUpdate;

}

...and in Trigger B (relevant code):

if( !updateMap.containsKey((String)accObj.get('Id') ) ) { //check that Acc Id not already added
   updateMap.put((String)accObj.get('Id'), (Account)accObj);

   if(updateMap.size() >= 199) {
      Database.update( updateMap.values() );
   }
}

....and later for the "remainders"......

Database.update( updateMap.values() );
PiggybackTriggerManager.PBOppFromAccountCheck = true;

So what I'd be wanting is a second "Map" set that is Static and could be checked while in the first FOR loop. If the item being set with .add(a) is already in that Static set, it would NOT add it. Help?!

1 Answer 1

3

You need to create a static variable that lives in a class somewhere and not in your apex trigger.

public static boolean firedOppRollup;

You can then set this variable from one trigger and reference it from another. The static variable can be set without instantiating your class. This is the recursion issue that I was alluding to in your other thread.

I can't really see all of your code in Trigger B but I'm assuming that it aggregates some opp data and then updates the account. You want to short-circuit the account trigger running at that point, since you've already completed your calculation in Trigger B. To put this into practice, you need to set the static variable to TRUE at the end of Trigger B, before your account DML.

Then in Trigger A, wrap all of your processing in an IF statement that checks your variable.

IF(MyClass.firedOppRollup){
    //Do nothing, the calculation is done
} else {
    //run all of your account trigger code
}
6
  • So you're taking an even simpler approach of putting the "checkbox" functionality into a static (in a Class) and then the code I've been trying to use will work (because it doesn't care about the Locked record when clearing the "checkbox" - the checkbox is in the class). Interesting. I will try this. Thanks.
    – AMM
    Apr 3, 2013 at 16:29
  • Good lord.... how do I set "firedOppRollup" from within Trigger B?? >:-( It's obviously not just "MyClass.firedOppRollup == true;" (sigh)
    – AMM
    Apr 3, 2013 at 17:48
  • Idiot (me). Changed == to =.
    – AMM
    Apr 3, 2013 at 17:54
  • I updated the code in my Question to match what I now have (I have the static in my existing Class FYI). It's back to being a cyclic problem, which tells me the "= true" is never firing apparently. The "= true" is simply at the end of the Trigger B, not inside any IFs/etc. Help? :-/
    – AMM
    Apr 3, 2013 at 18:22
  • 1
    Got it. I needed to set the TRUE before ever doing the updates to Account (it was doing it AFTER and it as not TRUE yet when re-calling Trigger A). THANKS SO MUCH.
    – AMM
    Apr 3, 2013 at 18:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .