+ Start a Discussion
Todd B.Todd B. 

Too many DML statements: 151

I need some help.  I created a batch process, that updates a group of records every morning.  Everything works fine in my sandbox but when I moved the code over to production and started running it, I get the following error:
Apex script unhandled exception by user/organization: ################/##################

Failed to process batch for class 'BatchUpdate_ServiceCenter_Enrollment' for job id '7075000000hItM9'

caused by: System.LimitException: Too many DML statements: 151

Class.BatchUpdate_ServiceCenter_Enrollment.execute: line 14, column

Here is the Batch Class
global class BatchUpdate_ServiceCenter_Enrollment implements Database.Batchable<sObject>
{
    global Database.QueryLocator start(Database.BatchableContext BC)
    {
        String query = 'SELECT Id,Auto_Update__c FROM Enrollment_Base__c ';
        return Database.getQueryLocator(query);
    }
 
    global void execute(Database.BatchableContext BC, List<Enrollment_Base__c> scope)
    {
        for (Enrollment_Base__c eb : scope){

         if(eb.Auto_Update__c == True)
          update eb;

        }
    }  

global void finish(Database.BatchableContext BC)
    {
   // Get the ID of the AsyncApexJob representing this batch job
    // from Database.BatchableContext.
    // Query the AsyncApexJob object to retrieve the current job's information.
    AsyncApexJob a = [Select Id, Status, NumberOfErrors, JobItemsProcessed,
                        TotalJobItems, CreatedBy.Email
                        from AsyncApexJob where Id = :BC.getJobId()];
    // Send an email to the Apex job's submitter notifying of job completion.
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    String[] toAddresses = new String[] {a.CreatedBy.Email};
    mail.setToAddresses(toAddresses);
    mail.setSubject('Batch Apex Update Event ' + a.Status);
    mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems +
                            ' batches with '+ a.NumberOfErrors + ' failures.' );
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }

}
Here is the Update Class
public with sharing class Update_Enrollement {
/* 
  Developer     : Jim Jackson
  Created       : 08/12/2014
  Last Modified : 
  Test Class    : 
  Objective     : 
  
*/ 

    public void beforeUpdate(Enrollment_Base__c[] newlist){
        List<Date> dtStart =  new List<Date>();
        List<Date> dtEnd =  new List<Date>();
        String strKey;
        Double GMAmount = 0 ;
        Boolean strStatus ;
        String strName;

            for(Enrollment_Base__c EB : newList){
              dtStart.add(EB.Start_Date__c);    
              dtEnd.add(EB.End_Date__c);
              strKey = EB.Service_Center__c;   
              strStatus = EB.Auto_Update__c;
              strname = EB.id;
            }
                
                System.debug(strKey);
                System.debug(dtStart);
                System.debug(dtEnd);
                System.debug(strName);
           
    If(strstatus = true){
        List<aggregateResult> fpresults = [select Count(Id) Total from SD_Mbr_Enroll_Cycles__c 
                                             where Use_Me__c = True
                                             And Enrollment_Status__c = 'Enrolled'
                                             And Enrollment_Status_Date__c >= :dtStart
                                             And Enrollment_Status_Date__c <= :dtEnd
                                             And Service_Center_Id__c = :strKey.SubString(0,15)];           
        for (AggregateResult ar : fpresults )  {
            GMAmount = (Double)ar.get('Total');
                }
            
        for(Enrollment_Base__c GM : newList){
            GM.Enrolled__c =  GMamount;
            GM.id = strname; 
                }   


    }
    }
}

Here is the Trigger
trigger EnrollmentUpdating on Enrollment_Base__c (after delete, after insert, after undelete, 
after update, before delete, before insert, before update) {


if(trigger.isUpdate && trigger.isBefore){
            Update_Enrollement Handler = new Update_Enrollement();
            handler.beforeUpdate(Trigger.new); 
    }  
}

Any Ideas?
kibitzerkibitzer
Your execute statement is not bulk-safe

11         for (Enrollment_Base__c eb : scope){
12 
13          if(eb.Auto_Update__c == True)
14           update eb;
15 
16         }

Your code should look something like this:

List<Enrollment_Base__c> toupdate = new List<Enrollment_Base__c>();
for (Enrollment_Base__c eb : scope){

          if(eb.Auto_Update__c == True)
           toupdate.add( eb);

         }
if(toupdate.size()>0) update toupdate;
Todd B.Todd B.
Thanks for the relpy @kibitzer.  I tried your code and I ran into a problem  It now updates every record to the same value?  So in this case, every "enrolled" field was up dated to the same value.  Where prior the "enrolled" field was updated to the correct number.  Any thoughts? 
kibitzerkibitzer

Well, the only thing that has changed is that your EnrollmentUpdating trigger is receiving a batch of objects instead of processing them one at a time. So there must be a logic error in that trigger or more specifically the Update_Enrollement handler class.
 

Dan