function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
BroncoBoyBroncoBoy 

Batch Apex Error: Batchable Instance Is Too Big

I have a batch class that collects values from the contact custom field YTD_GDC_Total__c and totals them at the account level and then inserts to totals into the associated custom account field.  I have an example of the code below showing one field being summed/totaled.  

 

I've begun adding additional fields (beyond what is shown in the code below) and, finally, after I added the last two fields, I'm now getting Batchable Instance Is Too Big error.  

 

I found this threadwhich I think may describe the cause of my error: "..(having a) global variable  which was keeping instances of lists of records that were created in each execution of the method 'execute' " - I think I'm keeping too many map collections in memory.  Any thoughts on how to resolve or does anyone know if a more efficient code pattern to summarize contact field @ the account level (without using aggregate queries)?

 

Thanks in advance!

 

CODE:

 

global class BatchAccntSummary implements Database.Batchable<sObject>, Database.Stateful

{

  public String query = 'SELECT Id, Name, AccountId, Account.RecordTypeId, Account.Name, YTD_GDC_Total__c ' +

                'FROM Contact WHERE Account.RecordTypeId = \'012500000009WdF\' ' +

                'AND (YTD_GDC_Total__c > 0.00)';  

  global Map<Id, Account> branchesToUpt = new Map<Id, Account>();

  global Boolean uniqueFirm = true;

  global Boolean addMapToList;

  global Integer counter = 0;

  global Map<Id, Decimal> branch_total_YTD_GDC;

  global Decimal total_YTD_GDC_Cont;

  global Decimal currbranch_total_YTD_GDC;

 

  /* 

  * OBJECTIVE:       Method used to initialize all the variables once.

  */

  global void initVars()

{

    branchesToUpt = new Map<Id, Account>();

    uniqueFirm = true;

    counter = 0;

 

  // YTD GDC TOTAL

  branch_total_YTD_GDC = new Map<Id, Decimal>();

  total_YTD_GDC_Cont = 0.00;

  currbranch_total_YTD_GDC = 0.00;  

}

 

  /* 

  * OBJECTIVE:       Start method of the Batchable interface 

  */

  global database.querylocator start(Database.BatchableContext BC)

  {

    initVars();

    return Database.getQueryLocator(query);

  }

 

  /* 

  * OBJECTIVE:       Utility method needed to handle null values.

  */

  global Decimal formatDecimal(Decimal valToFormat)

  {

    Decimal processedValue = 0.00;

    if (valToFormat != null)

      processedValue = valToFormat;

    else

      processedValue = 0.00; 

    return processedValue; 

  }

  

  /* 

  * OBJECTIVE:       Execute method of the Batchable interface 

  */

  global void execute(Database.BatchableContext BC, List<sObject> scope)

  {

    Account currAccnt;

    for (sObject s : scope) {

      addMapToList = false;

      uniqueFirm = true;    

      Contact c = (Contact)s;

 

total_YTD_GDC_Cont  = formatDecimal(c.YTD_GDC_Total__c);

 

      System.debug('Processing contact: ' + c.Name);

      // DEBUG Stuff

      System.debug('######## Size of branch_total_YTD_GDC _Map: ' + branch_total_YTD_GDC.size());

     

      // Check if the map already contains the firm id

      if (branch_total_YTD_GDC.containsKey(c.AccountId)) {

        uniqueFirm = false

      } 

     

      // If the map does not contain the firm id

      if (uniqueFirm) {

        System.debug('###### Size of m: ' + branch_total_YTD_GDC.size());

       

        branch_total_YTD_GDC.put(c.AccountId, total_YTD_GDC_Cont);

       

        currAccnt = new Account(Id = c.AccountId, Branch_Total_YTD_GDC__c = branch_total_YTD_GDC.get(c.AccountId));

 

        System.debug('Adding account: ' + c.Account.Name + ' w/ sales: ' + branch_total_YTD_GDC.get(c.AccountId) +

                    ', contact person: ' + c.Name);    

 

      }

      // If the map does contain the firm id

      else if (!uniqueFirm) {

          if (branch_total_YTD_GDC.containsKey(c.AccountId)) {

         

            currbranch_total_YTD_GDC = branch_total_YTD_GDC.get(c.AccountId);

           

            branch_total_YTD_GDC.put(c.AccountId,(total_YTD_GDC_Cont + currbranch_total_YTD_GDC));

           

            currAccnt = new Account(Id=c.AccountId,Branch_Total_YTD_GDC__c = branch_total_YTD_GDC.get(c.AccountId));                                    

                                   

            System.debug('Account: ' + c.Account.Name + ' w/ sales: ' + branch_total_YTD_GDC.get(c.AccountId) +

                        ', contact person: ' + c.Name);                        

          } 

      }

      if (currAccnt != null)

        branchesToUpt.put(c.AccountId, currAccnt);

    }

    update branchesToUpt.values();

    branchesToUpt.clear();

  }

 

  /* 

  * OBJECTIVE:       Batch finish Method.

  */

  global void finish(Database.BatchableContext BC)

  {

 

  }

}

 
Best Answer chosen by Admin (Salesforce Developers) 
magicforce9magicforce9

Hi,

 

Is there any specific reason that you are using Database.Stateful in your batch class definition ? I don't see you are processing any sort of aggregation in the finish method. You can take off  Database.Stateful  and use a lower number in optional scope parameter when executing the batch job..for eg Database.executeBatch(new BatchAccntSummary(), <some lower number like 100,200>) 

 


All Answers

magicforce9magicforce9

Hi,

 

Is there any specific reason that you are using Database.Stateful in your batch class definition ? I don't see you are processing any sort of aggregation in the finish method. You can take off  Database.Stateful  and use a lower number in optional scope parameter when executing the batch job..for eg Database.executeBatch(new BatchAccntSummary(), <some lower number like 100,200>) 

 


This was selected as the best answer
BroncoBoyBroncoBoy

Magicforce9 thank you for your response!  I had the same thought as you, but because we're summing in the execute method we need to maintain state .  I tried taking out Database.Stateful but it wouldn't sum anymore.  However I did reduce the scope number and that is working, so thanks!

 

One final question:  do you know if there are any forum that I could search to see if there are other code solutions...just for my own knowledge?

magicforce9magicforce9

I'm glad lowering the number worked. You can post your question on http://salesforce.stackexchange.com for others opinions.