[SalesForce] Too many DML rows: 10001 issue

I have a trigger that works perfectly in my sandbox. When I try to deploy, I get the following error message:

receiving_Tests.receiving_Trigger_Tests(), Details:
System.LimitException: Too many DML rows: 10001
Class.LookupCalculation.Calculate: line 50, column 1
Trigger.RecRollup: line 22, column 1

I'm thinking I need to be utilizing a "for" loop in my trigger? Not sure what the issue is. Any help/suggestions is greatly appreciated!

Trigger

trigger RecRollup on Receiving__c (after insert,after update,after delete,after undelete) {

    /*******************TO BE CUSTOMIZED*********************/
    string mysobjectParent = 'Field__c',      // Parent sobject API Name
           myrelationName = 'RecRpts__r', // Api name of the relation between parent and child (ends with __r)
           myformulaParent = 'Rollup_RecRpts__c',        // Api name of the number field that will contain the calculation
           mysobjectChild = 'Receiving__c',  // Child sobject API Name
           myparentfield = 'Field__c', // Api name of the lookup field on chield object
           myfieldChild = 'Value_for_MA__c',
         myfieldChild2 = 'Include_in_Settlement__c'; // Api name of the child field to roll up

    LookupCalculation.Method method = LookupCalculation.Method.SUM; //Selected method: could be COUNT, SUM, MIN, MAX, AVG
    /*******************************************************/

    LookupCalculation calculation = new LookupCalculation(mysobjectParent, myrelationName, myformulaParent,
                                                          mysobjectChild, myparentfield, myfieldChild, myfieldChild2);
    List<sobject> objList = new List<sobject>((List<sobject>) Trigger.new);
    if(Trigger.isDelete)
        objList = Trigger.old;
    if(Trigger.isUpdate)
        objList.addAll((List<sobject>) Trigger.old);
    calculation.calculate(method, objList);
}

Class:

public class LookupCalculation{

    public enum Method {COUNT, SUM, MIN, MAX, AVG} 

    private string sobjectParent, 
                   relationName, 
                   formulaParent, 
                   sobjectChild, 
                   parentfield, 
                   fieldChild,
             fieldChild2;

    public LookupCalculation(string mysobjectParent, string myrelationName, string myformulaParent,
                             string mysobjectChild, string myparentfield, string myfieldChild, string myfieldChild2){
        sobjectParent = mysobjectParent;
        relationName = myrelationName;
        formulaParent = myformulaParent;
        sobjectChild = mysobjectChild;
        parentfield = myparentfield;
        fieldChild = myfieldChild;
        fieldChild2 = myfieldChild2;                         
    }

    public void Calculate(Method calculation, List<sobject> childList){
        set<Id> parentIdSet = new set<Id>();
        for(sobject sobj : childList)
            parentIdSet.add((Id) sobj.get(parentfield));
         string soqlParent = 'select id, (select ' + fieldChild + ',' + fieldChild2 + ' from ' + relationName + ' where ' + fieldChild2 + ' = True'+ ') from ' + sobjectParent ;
        List<sobject> parentList = Database.query(soqlParent);
        for(sobject parent : parentList){
            List<sobject> children = parent.getSObjects(relationName);
            if(children == null)
                children = new List<sobject>();
            Decimal counter = (mustSum(calculation))? 0 : null;
            if(calculation == Method.COUNT)
                counter = children.size();
            for(sobject child : children){
                Decimal value = (Decimal) child.get(fieldChild);
                if(mustSum(calculation) && value != null)
                    counter += value;
                else if(calculation == Method.MIN && (counter == null || value < counter))
                    counter = value;
                else if(calculation == Method.MAX && (counter == null || value > counter))
                    counter = value;
            }
            if(calculation == Method.AVG && children.size() > 0)
                counter = counter / children.size();
            parent.put(formulaParent, counter);
        }
        update parentList;
    }

    private boolean mustSum(Method calculation){
        return (calculation == Method.SUM || calculation == Method.AVG);
    }

}

Test Class

@isTest

private class receiving_Tests {

static Account testFarmerAccount = testHelper_Methods.account_insertTestRecord();
static Sesaco_Contract__c testMA = testHelper_Methods.ma_InsertTestRecord(testFarmerAccount);
static Field__c testField = testHelper_Methods.field_InsertTestRecord(testMA, testFarmerAccount);
static Field__c testField2 = testHelper_Methods.field_InsertTestRecord(testMA, testFarmerAccount);

static testMethod void receiving_Trigger_Tests() {
    test.startTest();
        Receiving__c testReceiving = common_Methods.insertTest_Receiving(testFarmerAccount.Id, testMA.Id, testField.Id);
        testReceiving.GRLBS__c = 5;
        testReceiving.Field__c = testField2.Id;
        update testReceiving;

        delete testReceiving;

        undelete testReceiving;

    test.stopTest();
}

static testMethod void receiving_Extension_Tests() {
    test.startTest();
        ApexPages.StandardController sc = new ApexPages.standardController(new Receiving__c());
        receiving_Extension ext = new receiving_Extension(sc);

        ext.getCropYearOptions();
        ext.getFarmerOptions();
        ext.getreceivingLocationOptions();
        ext.newField();
        ext.newLocation();
        ext.reRender();
        ext.save();

    test.stopTest();
}

static testMethod void gradeCalc_Test(){
    Double MoistGr = 1;
    Double DockGr = 1;
    Double LabTWGr = 2;
    Double DamgGr = 1;
    Double FMGr = 1;
    Double BrokGr = 6;
    Double OseedGr = 1;
    Double Grade = 4;
    List<Double> gradeList = new Double[]{MoistGr,DockGr,LabTWGr,DamgGr,FMGr,BrokGr,OseedGr};
    test.startTest();
        System.assertEquals(Grade, Receiving_Methods.getGrade(gradeList));

        MoistGr = 1;
        DockGr = 1;
        LabTWGr = 1;
        DamgGr = 1;
        FMGr = 6;
        BrokGr = 6;
        OseedGr = 1;
        Grade = 6;
        gradeList = new Double[]{MoistGr,DockGr,LabTWGr,DamgGr,FMGr,BrokGr,OseedGr};
        System.assertEquals(Grade, Receiving_Methods.getGrade(gradeList));

        MoistGr = 2;
        DockGr = 1;
        LabTWGr = 1;
        DamgGr = 1;
        FMGr = 3;
        BrokGr = 1;
        OseedGr = 1;
        Grade = 2;
        gradeList = new Double[]{MoistGr,DockGr,LabTWGr,DamgGr,FMGr,BrokGr,OseedGr};
        System.assertEquals(Grade, Receiving_Methods.getGrade(gradeList));

        MoistGr  = 1;
        DockGr = 1;
        LabTWGr = 1;
        DamgGr = 1;
        FMGr = 1;
        BrokGr = 1;
        OseedGr = 1;
        Grade = 1;
        gradeList = new Double[]{MoistGr,DockGr,LabTWGr,DamgGr,FMGr,BrokGr,OseedGr};
        System.assertEquals(Grade, Receiving_Methods.getGrade(gradeList));

        MoistGr  = 5;
        DockGr = 1;
        LabTWGr = 8;
        DamgGr = 3;
        FMGr = 7;
        BrokGr = 2;
        OseedGr = 1;
        Grade = 8;
        gradeList = new Double[]{MoistGr,DockGr,LabTWGr,DamgGr,FMGr,BrokGr,OseedGr};
        System.assertEquals(Grade, Receiving_Methods.getGrade(gradeList));
    test.stopTest();
}

Best Answer

Your unit tests should not be operating on data which exists in your production org.

If the receiving_Tests class is annotated with @seeAllData=true, switch it to false and then create all of the data that you need for the test within the test itself.

If the receiving_Tests class has an API version earlier than v24, you should modify it to v24 or later, make any other corrections to the tests so that it passes all tests and deploy it to production as well.

This looks to be a good opportunity for you to test your Large Data Volume performance by creating more than 10,000 records in the setup for your test and ensuring that the test is successfully executed in the sandbox.

Isolation of Test Data from Organization Data in Unit Tests

Related Topic