You need to sign in to do that
Don't have an account?
SeanCeno
Batch Apex for Account Hierarchy
All,
I'm trying to refactor my trigger code to a batch. How can I execute my class to fire within the batch?
Class
Batch:
I'm trying to refactor my trigger code to a batch. How can I execute my class to fire within the batch?
Class
public class Account_RollupProductInterest { protected final Account[] accountNewList; protected final Account[] accountOldList; Set<Id> acctIds = new Set<Id>(); Decimal RXRsum = 0; Decimal A40Actsum = 0; Decimal DSTsum = 0; Decimal PPsum = 0; Decimal ITSum = 0; Decimal ActiveRepsSum = 0; Decimal NSTickets = 0; public Account_RollupProductInterest(Account[] accountOldList, Account[] accountNewList) { this.accountNewList = accountNewList; this.accountOldList = accountOldList; } public Account_RollupProductInterest(){ new Account_RollupProductInterest().executeTableRollup(); } //Update Numbers Table public void executeTableRollup(){ for(Account a : accountNewList){ if(a.ParentId != null){ acctIds.add(a.ParentId); } } List<Account> updAcc = new List<Account>(); List<Account> childAccts = new List<Account>([Select Id, Number_of_NS_RXR_Propects__c, Number_of_40_Act_Fund_Prospects__c, Number_of_DST_Prospects__c, Number_of_Private_Placement_Prospects__c, Number_of_Investor_Tickets__c, Number_Of_Active_Reps__c, Number_of_NorthStar_Tickets__c, (Select Id, Number_of_NS_RXR_Propects__c, Number_of_40_Act_Fund_Prospects__c, Number_of_DST_Prospects__c, Number_of_Private_Placement_Prospects__c, Number_of_Investor_Tickets__c, Number_Of_Active_Reps__c, Number_of_NorthStar_Tickets__c From ChildAccounts) From Account Where Id in :acctIds]); for(Account acc : childAccts){ for(Account child : acc.ChildAccounts){ RXRsum += (child.Number_of_NS_RXR_Propects__c != null ? RXRsum + child.Number_of_NS_RXR_Propects__c : 0); acc.Number_of_NS_RXR_Propects__c = RXRsum; A40Actsum += (child.Number_of_40_Act_Fund_Prospects__c != null ? A40Actsum + child.Number_of_40_Act_Fund_Prospects__c : 0); acc.Number_of_40_Act_Fund_Prospects__c = A40Actsum; DSTsum += (child.Number_of_DST_Prospects__c != null ? DSTsum + child.Number_of_DST_Prospects__c : 0); acc.Number_of_DST_Prospects__c = DSTsum; PPsum += (child.Number_of_Private_Placement_Prospects__c != null ? PPsum + child.Number_of_Private_Placement_Prospects__c : 0); acc.Number_of_Private_Placement_Prospects__c = PPsum; ITSum += (child.Number_of_Investor_Tickets__c != null ? ITSum + child.Number_of_Investor_Tickets__c : 0); acc.Number_of_Investor_Tickets__c = ITSum; ActiveRepsSum += (child.Number_Of_Active_Reps__c != null ? ActiveRepsSum + child.Number_Of_Active_Reps__c : 0); acc.Number_Of_Active_Reps__c = ActiveRepsSum; NSTickets += (child.Number_Of_NorthStar_Tickets__c != null ? NSTickets + child.Number_Of_NorthStar_Tickets__c : 0); acc.Number_Of_NorthStar_Tickets__c = NSTickets; } updAcc.add(acc); } try { update updAcc; } Catch (Exception e) { System.debug('Exception : '+e.getMessage()); } } }
Batch:
Batch: global class Contact_RollupProductInterestBatchable implements Database.Batchable<sObject> { global Database.QueryLocator start(Database.BatchableContext batchableContext){ return Database.getQueryLocator('Select Id From Account'); /**String query = 'Select Id, Number_of_NS_RXR_Propects__c,' + 'Number_of_40_Act_Fund_Prospects__c,' + 'Number_of_DST_Prospects__c,' + 'Number_of_Private_Placement_Prospects__c,' + 'Number_of_Investor_Tickets__c,' + 'Number_Of_Active_Reps__c,' + 'Number_of_NorthStar_Tickets__c,' + '(Select Id, Number_of_NS_RXR_Propects__c,' + 'Number_of_40_Act_Fund_Prospects__c,' + 'Number_of_DST_Prospects__c,' + 'Number_of_Private_Placement_Prospects__c,' + 'Number_of_Investor_Tickets__c,' + 'Number_Of_Active_Reps__c,' + 'Number_of_NorthStar_Tickets__c' + 'From ChildAccounts)' + 'From Account'; return Database.getQueryLocator(query);**/ } global void execute(Database.BatchableContext batchableContext, Account[] accountNewList) { // Execute the rollup. It will auto-update the branch accounts once complete for(Account a : accountNewList){ a.Number_of_NS_RXR_Propects__c = a.ChildAccounts.Number_of_NS_RXR_Propects__c; a.Number_of_40_Act_Fund_Prospects__c = a.ChildAccounts.Number_of_40_Act_Fund_Prospects__c; a.Number_of_DST_Prospects__c = a.ChildAccounts.Number_of_DST_Prospects__c; a.Number_of_Private_Placement_Prospects__c = a.ChildAccounts.Number_of_Private_Placement_Prospects__c; a.Number_of_Investor_Tickets__c = a.ChildAccounts.Number_of_Investor_Tickets__c; a.Number_Of_Active_Reps__c = a.ChildAccounts.Number_Of_Active_Reps__c; a.Number_of_NorthStar_Tickets__c = a.ChildAccounts.Number_of_NorthStar_Tickets__c; } update accountNewList } global void finish(Database.BatchableContext batchableContext) { } }
Now you are all set to execute your batch.
Also note that the SOQL in executeTableRollup can easily hit "SOQL Query Rows" Limit. With the deafult batch size 200 you can support the below numbers 200 Account with 500 child accounts( makes 50000 Query rows). If you hit the limit try to set the batch size to lower number.
All Answers
Now you are all set to execute your batch.
Also note that the SOQL in executeTableRollup can easily hit "SOQL Query Rows" Limit. With the deafult batch size 200 you can support the below numbers 200 Account with 500 child accounts( makes 50000 Query rows). If you hit the limit try to set the batch size to lower number.
Any ideas? And also, in order to avoid the governor limits should I pull the SOQL out of the childAccts list? I tried to do it with an Aggregate Result, but I couldn't figure out how to use a subquery with it.
Having small batchSize does not hurt. Only when you have above 50k child account for a single parent then you need to worry about.