5

I had a use case where i had to traverse through account hierarchy (whose business limit is infinite). So i tried coding myself(i am new to APEX :() and came up with a recursive kind of function.It works,but due to recursiveness ,it goes back to called function,and executes few lines below it.and i cannot find a exit kind of function in apex as well.
can someone please review my code and see how can i go back to my trigger,immediately when i find the return value. although code works fine,when i bulk test it sometimes fail,what is the maximum number of data we should pass via testclass for bulk test,it works for me when i create 200accounts but when i give accounts upto 1000 its fine.but after that it says too many code statements

My usecase is given detailed at : Account SOQL traverse

Code :

Trigger:

    trigger GEN_BeforeInsertUpdate on Account (before insert,before update) {
Account VGEorTopParent = new account();
testclass obj = new testclass();
integer queryLimit = Limits.getLimitQueryRows()-Limits.getQueryRows();
List<account> existingAccounts = [select parentID,Is_VGE_Account__c from Account limit :queryLimit ];
for (Account currAcc :Trigger.new)
{
    //Checking whether current Account has a parent.Only if it has a parent execute all logic
    if (currAcc.ParentId != null)
      {   

         // for(List<Account> acclist :existingAccounts)
             //   {
                 Map<ID, Account> parentMap = new Map<ID, Account>(existingAccounts);
                  //Looping through map values
                  if (!parentMap.isempty())
                  {
                  for (Account acc:parentMap.values())
                  {
                  if (acc.ID == currAcc.parentID)
                  {
                   VGEorTopParent = obj.getnextparent(acc, parentMap);
                   currAcc.Global_Ultimate__c =  VGEorTopParent.ID;
                    break;
                  }
                  }

                }
                 //  }

      }

Called method:

    public with sharing class testclass {
public account a = new account();
 account s = new account();
     public  Account getnextparent( Account inboundparent,Map<ID,Account>  inboundmap)
    {
       if (!inboundmap.isempty()) 
        {

            if (inboundparent.Is_VGE_Account__c)
        {
            inboundmap.clear();
            return (inboundparent);

        }
        else
        {

            s = inboundmap.get(inboundparent.ParentID);
            if ( s == null)
            {
            inboundmap.clear();
            return (inboundparent);

            }
         inboundmap.remove(inboundparent.Id);
         a = getnextparent(s,inboundmap);
         return(a);
          }

        }
        else
        {
            return a;

        }

    }
}
  • 1
    This will only work if the total number of Accounts in your organization is small enough that you can query for all of them at once. Once you have too many Accounts, this trigger will no longer work properly. – Jeremy Nottingham Jul 21 '13 at 15:13
  • hmm.if there is no business limit for account hierarchy,do you think this method,or soql in a loop is a better idea – sfdc99999 Jul 21 '13 at 15:35
  • If you are able to enforce a sensible depth limit to your account hierarchy, you can use a select to get all of them in one soql query using Id, parent.id, parent.parent.id,.... You can do this 5 levels deep. – techtrekker Jul 21 '13 at 15:57
  • 1
    I would also consider doing such a large data manipulation operation via scheduled batch apex rather than real time in a trigger. – techtrekker Jul 21 '13 at 16:10
  • 1
    If you honestly think there might be account hierarchies with 1000 or more levels, you would have to build it out to a batch process, since any other method will have trouble with limits. Frankly, I don't understand the business need for that scale of hierarchies. – Jeremy Nottingham Jul 22 '13 at 2:18
6

Although I agree with Tech and Jeremy that this really belongs in a batch job, not a trigger. If you really want to do it this way you just need to set a static variable in a global class. I use this to prevent triggers from firing more than once. You can see the basic way to do this in the following post.

http://boards.developerforce.com/t5/Apex-Code-Development/Trigger-is-fired-twice-due-to-the-workflow-rule-field-update/td-p/123469

This will allow you to stop the execution, but again to stress, this really isn't something that should be handled in a trigger at all.

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.