+ Start a Discussion
Vladimir BessonovVladimir Bessonov 

how to rewrite class to for Batch Apex operations (DML > 10000)

Hello Everyone. 

I was using the code below testing it on small amount of records, it worked fine till I used in sandbox with lots of records. 

Please advise how to rewrite into Batch apex code.
 
/******************************************************************************
Trigger for Class that implements batchable 
*/


trigger ProjectCreateTrigger on Component_Project__c (after insert) {

    String ProjectConfigID;
    String ProjectID;
  
    for (Component_Project__c c : Trigger.new) {
//         // c - is created new Project where the records shall be added

         ProjectConfigID = c.Project__c;  
        ProjectID = c.ID;
       
     }

    database.executebatch(new BatchProjectCreate(ProjectConfigID, ProjectID),200);

 }



/******************************************************************************
Class implement Batchable 
*/

public with sharing class BatchProjectCreate  implements Database.Batchable<sObject> {

    public BatchProjectCreate(String ProjectConfigID, String ProjectID) {

    Integer VehicleFleetStartNumber;

    ComponentProjectConfiguration__c ProjectConfig = [Select ID, Name, Vehicle_fleet_start_number__c from ComponentProjectConfiguration__c where ID =: ProjectConfigID];
    VehicleFleetStartNumber = Integer.valueOf(ProjectConfig.Vehicle_fleet_start_number__c);

    List<NonSerializedPart__c> NonSerPartsConfig = [Select ID, Name, Number_of_units__c, Quantity__c, Unit_of_measurement__c, Material_Number__c, Supplier_Part_Number__c, Supplier__c from NonSerializedPart__c where Project__c =: ProjectConfigID];
    
    // CREATE NON SERIALIZED PART RECORDS FOR THE PROJECT 
    
    List<project_Non_Serialized_Part__c> NonSerParts = new List<project_Non_Serialized_Part__c>();
    List<Acceptance__c> NonSerPartAcceptances = new List<Acceptance__c>();  
    for (NonSerializedPart__c part : NonSerPartsConfig) {
           Double Total = part.Number_of_units__c * part.Quantity__c;
            project_Non_Serialized_Part__c NewPart = New project_Non_Serialized_Part__c(Name = part.Name, Project__c =ProjectID,
             Material_Number__c = part.Material_Number__c, Supplier__c = part.Supplier__c, 
             Supplier_Part_Number__c = part.Supplier_Part_Number__c, 
             Total_Quantity__c = Total ,Unit_of_measurement__c = part.Unit_of_measurement__c,
             Number_of_units__c = part.Number_of_units__c, unit_Quantity__c = part.Quantity__c);

         NonSerParts.add(NewPart);
           }  

    try {
         insert NonSerParts;	
	 } catch (system.Dmlexception e) {
	 	system.debug (e);
     }

     for(project_Non_Serialized_Part__c part : NonSerParts){ 
                
        for(Integer i=0;i<part.Number_of_units__c;i++){
                Acceptance__c newAcceptance = new Acceptance__c(Non_Serialized_Part__c = part.id, Quantity__c = part.unit_Quantity__c,
                Unit_of_measurement__c = part.Unit_of_measurement__c, Acceptance_Non_Serialized_Part__c = part.Name, Status__c = 'NOT SENT');
             
                NonSerPartAcceptances.add(newAcceptance);
        }
    }

    try {
        insert NonSerPartAcceptances;	
    } catch (system.Dmlexception e) {
        system.debug (e);
    }
// Serialized Sets and Parts Creation 
    List<SerializedPartsSet__c> SerPartsSetConfig = [Select ID, Name, Quantity__c from SerializedPartsSet__c where Project__c =: ProjectConfigID];
    List<project_Serialized_Parts_Set__c> SerPartsSets = new List<project_Serialized_Parts_Set__c>();
    List<project_Serialized_Part__c> SerParts = new List<project_Serialized_Part__c>();

    for (SerializedPartsSet__c partSet : SerPartsSetConfig) {

    //   Double Total = part.Number_of_units__c * part.Quantity__c;
       project_Serialized_Parts_Set__c NewPartSet = New project_Serialized_Parts_Set__c(Name = partSet.Name, Project__c =ProjectID, Quantity__c = partSet.Quantity__c);
         SerPartsSets.add(NewPartSet);
       } 
 
    try {
        insert SerPartsSets;
	
    } catch (system.Dmlexception e) {
        system.debug (e);
    }

    // SerializedPartsSet__c ConfPartSet = [Select ID, Name, Project__c from SerializedPartsSet__c 
    // where Project__c =: ProjectConfigID AND Name =: partSet.Name];

    // insert Parts
    for(project_Serialized_Parts_Set__c partSet: SerPartsSets){ 
        // ITERATE PART SETS. PROPULSION & TRUCK    

        SerializedPartsSet__c ConfPartSet = [Select ID, Name, Project__c from SerializedPartsSet__c 
        where Project__c =: ProjectConfigID AND Name =: partSet.Name];
        List <SerializedPart__c> SerPartsConfig = [Select ID, Name, Quantity__c,
         Material_Number__c, Supplier_Part_Number__c, Supplier__c from SerializedPart__c 
         where SerializedPartSet__c =: ConfPartSet.ID];

        // ITERATE OVER SETS - for example 400
        for(Integer i=0; i<partSet.Quantity__c;i++){

            for(SerializedPart__c part: SerPartsConfig){

                // IF QUANTITY IS NOT ONE, ITERATE OVER THE QUIANITY AND INSERT RECORD FOR EACH 
                if( part.Quantity__c == 1) {
                    system.debug('PART QUANTITY is 1:' + part.Quantity__c ); 
                   
                    project_Serialized_Part__c newPart = new project_Serialized_Part__c(
                        Name= part.Name, Quantity__c = part.Quantity__c , Material_Number__c = part.Material_Number__c, 
                        Set_Number__c = i + VehicleFleetStartNumber, Status__c = 'NOT SENT',
                        Supplier_Part_Number__c = part.Supplier_Part_Number__c, 
                        Supplier__c = part.Supplier__c, Serialized_Part_Set__c = partSet.ID); 
                      
                        SerParts.add(newPart);
                } else {
                    system.debug('PART QUANTITY is > 1:' + part.Quantity__c );
                    for(Integer j=0; j<part.Quantity__c; j++) {
                        project_Serialized_Part__c newPart = new project_Serialized_Part__c(
                            Name= part.Name, Quantity__c = 1 , Material_Number__c = part.Material_Number__c, 
                            Set_Number__c = i + VehicleFleetStartNumber, Status__c = 'NOT SENT',
                            Supplier_Part_Number__c = part.Supplier_Part_Number__c, 
                            Supplier__c = part.Supplier__c, Serialized_Part_Set__c = partSet.ID); 
                           
                            SerParts.add(newPart);
                    }
                }

            }

        }
    }

    try {
        insert SerParts;	

    } catch (system.Dmlexception e) {
        system.debug(e);
    }

    }

    // Non Serialized Parts creation 


}



 
SwethaSwetha (Salesforce Developers) 
HI Vladimir ,
The below posts should help you get started
https://salesforce.stackexchange.com/questions/253095/how-to-convert-the-apex-class-into-batch-apex-class
https://salesforce.stackexchange.com/questions/132504/help-in-converting-my-apex-class-to-batch-job
https://salesforce.stackexchange.com/questions/322233/convert-apex-method-to-batch
https://salesforce.stackexchange.com/questions/326121/how-can-i-convert-apex-method-into-batch

If this information helps, please mark the answer as best. Thank you
Vladimir BessonovVladimir Bessonov
IT would be nice to get complete example. 

what will be BC when I call the method later in the code? 
Vladimir BessonovVladimir Bessonov
ok. I did it, looks like it works but again I receive 

First error: Too many DML rows: 10001

Trigger code
trigger ProjectCreateTrigger on Component_Project__c (after insert) {

    String ProjectConfigID;
    String ProjectID;
  
    for (Component_Project__c c : Trigger.new) {
        // c - is created new Project where the records shall be added

        ProjectConfigID = c.Project__c;  
        ProjectID = c.ID;
       
    }
    BatchCreateNonSerializedParts NonSerPartsCreate = New BatchCreateNonSerializedParts(ProjectConfigID, ProjectID);
    Database.executeBatch(NonSerPartsCreate, 200);
    BatchCreateSerializedParts SerPartsCreate = New BatchCreateSerializedParts(ProjectConfigID, ProjectID);
    Database.executeBatch(SerPartsCreate, 200);
}
Classes 
 
public with sharing class BatchCreateNonSerializedParts implements Database.Batchable<sObject> {
    String ProjectConfigID;
    String ProjectID;
    Integer VehicleFleetStartNumber;
    ComponentProjectConfiguration__c ProjectConfig;

    List<NonSerializedPart__c> NonSerPartsConfig;
    List<project_Non_Serialized_Part__c> NonSerParts = new List<project_Non_Serialized_Part__c>();
    List<Acceptance__c> NonSerPartAcceptances = new List<Acceptance__c>();  

    public BatchCreateNonSerializedParts(String ProjectConfigID, String ProjectID) {
        this.ProjectConfigID = ProjectConfigID;
        this.ProjectID = ProjectID;

        // not Batch operations 

        ProjectConfig = [Select ID, Name, Vehicle_fleet_start_number__c from ComponentProjectConfiguration__c where ID =: ProjectConfigID];
        VehicleFleetStartNumber = Integer.valueOf(ProjectConfig.Vehicle_fleet_start_number__c);
        // it is Database.BatchableContext bc - context
       // NonSerPartsConfig = [Select ID, Name, Number_of_units__c, Quantity__c, Unit_of_measurement__c, Material_Number__c, Supplier_Part_Number__c, Supplier__c from NonSerializedPart__c where Project__c =: ProjectConfigID];
    }
    
    public Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator([Select ID, Name, Number_of_units__c, Quantity__c, Unit_of_measurement__c, Material_Number__c, Supplier_Part_Number__c, Supplier__c from NonSerializedPart__c where Project__c =: ProjectConfigID]);
    }

    public void execute(Database.BatchableContext bc, List<NonSerializedPart__c> NonSerPartsConfig) {

        for (NonSerializedPart__c part : NonSerPartsConfig) {
            Double Total = part.Number_of_units__c * part.Quantity__c;
             project_Non_Serialized_Part__c NewPart = New project_Non_Serialized_Part__c(Name = part.Name, Project__c =ProjectID,
              Material_Number__c = part.Material_Number__c, Supplier__c = part.Supplier__c, 
              Supplier_Part_Number__c = part.Supplier_Part_Number__c, 
              Total_Quantity__c = Total ,Unit_of_measurement__c = part.Unit_of_measurement__c,
              Number_of_units__c = part.Number_of_units__c, unit_Quantity__c = part.Quantity__c);
 
          NonSerParts.add(NewPart);
        }  

        try {insert NonSerParts;} catch (system.Dmlexception e) {system.debug (e);}

        for(project_Non_Serialized_Part__c part : NonSerParts){ 
                
            for(Integer i=0;i<part.Number_of_units__c;i++){
                        Acceptance__c newAcceptance = new Acceptance__c(Non_Serialized_Part__c = part.id, Quantity__c = part.unit_Quantity__c,
                        Unit_of_measurement__c = part.Unit_of_measurement__c, Acceptance_Non_Serialized_Part__c = part.Name, Status__c = 'NOT SENT');  
                        NonSerPartAcceptances.add(newAcceptance);
                }
            }
        try {insert NonSerPartAcceptances;} catch (system.Dmlexception e) { system.debug (e); }
    }
    public void finish(Database.BatchableContext bc){
        System.debug('Succesfully inserted Non Serialized parts and Acceptances');
    }
}

the whole point of using Batch Apex was to avoid DML limit...
 
Vladimir BessonovVladimir Bessonov
I think I know what is it. I used Database.BatchableContext bc wrong. it only applies to NonSerPartsConfig, that will not trigger DML failt anyway in my program (current use case), but insert operaiton will.

try {insert NonSerParts;} catch (system.Dmlexception e) {system.debug (e);} courses DML faulire. 

How to apply batch to insert operation?
public Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator([Select ID, Name, Number_of_units__c, Quantity__c, Unit_of_measurement__c, Material_Number__c, Supplier_Part_Number__c, Supplier__c from project_Non_Serialized_Part__c where Project__c =: ProjectConfigID]);
    }


Is it possible to avoid "batch hell"? 

 
jessica allmanjessica allman
I just couldn't evaporate from your site before proposing that I really acquired some remarkable encounters the standard data an individual provides for your guests? Will be again interminably to look at new posts. 
https://www.pinkyslondonescorts.co.uk/
jessica allmanjessica allman
If more individuals that construction articles included themselves with making remarkable substance like you, more perusers would be enthused about their works. I have taken in a specific number of things from your article. 
https://www.bursaescortservice.com/