0

I have a method which is returning Apex Execution Error: Too many DML rows: 10001

public void financialAccountforContactAndAccounts(List<Financial_Account_role__c> newFinancialAccountRoles)
        {
            if(!recursivetriggerhelper.isaccessTeamTriggerAccount()){ 
            system.debug('***Entering****');
            Set<Id> contactIds = new Set<ID>();
            Set<Id> accountIds = new Set<ID>();
            Set<Id> accountIdListforAST = new Set<Id>();

            Map<Id,Id> roleIdToTeamId = getRoleToTeamId();
            Map<Id,Id> accountFAcctMap = new Map<Id,Id>();
            List<Financial_Account_Role__c> fARoles = [select Financial_Account__c,contact__c,contact__r.accountid,contact__r.ownerid,contact__r.roleid__c,Organization__c,Organization__r.ownerid, Organization__r.roleid__c from Financial_Account_Role__c where id IN: newFinancialAccountRoles];
            for(Financial_Account_role__c far: fARoles)
            {
                if(far.contact__c != null)
                {
                contactIds.add(far.contact__c); 
                accountFAcctMap.put(far.contact__r.accountid,far.financial_account__c);               
            }
            else if(far.organization__c != null)
            {
                accountIds.add(far.Organization__c);
                accountIdListforAST.add(far.Organization__c);
                accountFAcctMap.put(far.Organization__c,far.financial_Account__c);
            }
        }

        Map<Id,Contact> contactList= new Map<Id,Contact>([select AccountId from Contact where Id IN :contactIds]);

        for(Contact c:contactList.values())
        {
            accountIdListforAST.add(c.accountid);
        }

        List<AccountTeamMember> accountAsts = [select userid,Accountid  from AccountTeamMember where accountid in: accountIdListforAST];

        List<Financial_Account__Share> listFAShares = new List<Financial_Account__Share>(); 
        system.debug('##faroles'+FARoles);
        for(Financial_Account_role__c far: fARoles) 
        {
            system.debug('##newcon'+far.contact__c); 
            system.debug('##newacc'+far.Organization__c);     
            if(far.contact__c!=null)
            {

                 system.debug('****insertFAShare****');
                 Financial_Account__Share faShare = new Financial_Account__Share();
                 faShare.AccessLevel = 'Edit'; 
                 faShare.ParentID = far.Financial_Account__c;
                 faShare.RowCause = Schema.financial_Account__share.RowCause.Manual;
                 faShare.UserOrGroupID = far.contact__r.ownerId;

                 if(far.contact__r.roleid__c !=null && roleIdToTeamId.get(far.contact__r.roleid__c) != null)
                 {
                 Financial_Account__Share faShareForTeam = new Financial_Account__Share();
                 faShareForTeam.AccessLevel = 'Edit'; 
                 faShareForTeam.ParentID = far.Financial_Account__c;
                 faShareForTeam.RowCause = Schema.financial_Account__share.RowCause.Manual;
                 faShareForTeam.UserOrGroupID = roleIdToTeamId.get(far.contact__r.roleid__c);
                 listFAShares.add(faShareForTeam);
                 }

                 for(AccountTeamMember ast: accountAsts)
                 {
                     if(ast.accountid == far.contact__r.accountid)
                     {
                         Financial_Account__Share faShareForATM= new Financial_Account__Share();
                         faShareForATM.AccessLevel = 'Edit'; 
                         faShareForATM.ParentID = far.Financial_Account__c;
                         faShareForATM.RowCause = Schema.financial_Account__share.RowCause.Manual;
                         faShareForATM.UserOrGroupID = ast.userid;
                         listFAShares.add(faShareForATM);
                     }
                 }


                 listFAShares.add(faShare);

            }    
            else if(far.Organization__c!=null)
            {
                //FAShare added for org owner
                 Financial_Account__Share faShare = new Financial_Account__Share();
                 faShare.AccessLevel = 'Edit'; 
                 faShare.ParentID = far.Financial_Account__c;
                 faShare.RowCause = Schema.financial_Account__share.RowCause.Manual;
                 faShare.UserOrGroupID = far.Organization__r.ownerId;

                 //FAShare added for org owner team
                 if((far.Organization__r.roleid__c)!=null && roleIdToTeamId.get(far.Organization__r.roleid__c)!=null)
                 {
                 Financial_Account__Share faShareForTeam = new Financial_Account__Share();
                 faShareForTeam.AccessLevel = 'Edit'; 
                 faShareForTeam.ParentID = far.Financial_Account__c;
                 faShareForTeam.RowCause = Schema.financial_Account__share.RowCause.Manual;
                 faShareForTeam.UserOrGroupID = roleIdToTeamId.get(far.Organization__r.roleid__c);
                 listFAShares.add(faShareForTeam);
                 }

                 for(AccountTeamMember ast: accountAsts)
                 {
                     if(ast.accountid == far.organization__c)
                     {
                         Financial_Account__Share faShareForATM= new Financial_Account__Share();
                         faShareForATM.AccessLevel = 'Edit'; 
                         faShareForATM.ParentID = far.Financial_Account__c;
                         faShareForATM.RowCause = Schema.financial_Account__share.RowCause.Manual;
                         faShareForATM.UserOrGroupID = ast.userid;
                         listFAShares.add(faShareForATM);
                     }
                 }


                 listFAShares.add(faShare);
             } 



        } 
        system.debug('FAShares'+listFAShares);  
        if(listFAShares.size() > 0)
        {
            Database.insert(listFAShares,false);
        }
        }
        recursivetriggerhelper.isaccessTeamTriggerAccount(); 

    }

The Last but 1 line Database.insert(listFAShares,false); That is where i am getting the error. How do i use Future method here?

  • 1
    The asynchronous limit for Total number of records processed as a result of DML statements is also 10k. Why do you think a @future method will help you? Chained Queueables might... – Adrian Larson Sep 7 '16 at 19:42
2

If you are facing Too many DML rows: 10001 error, I'd suggest to use a batch class instead a @future method as is noted here (check Future Method Performance Best Practices at the bottom of the page in the link). Batch classes let you handle large volume of records and avoid to hit limits.

For example, if you create a batch class for your code, it would be something like:

public class YourBatchClass implements Database.Batchable<sObject>{

    public Database.QueryLocator start(Database.BatchableContext BC){

       // Logic before to run the query

       String query = 'SELECT Financial_Account__c, contact__c, contact__r.accountid, contact__r.ownerid, ' +
                             'contact__r.roleid__c, Organization__c, Organization__r.ownerid, ' + 
                             'Organization__r.roleid__c ' + 
                      'FROM Financial_Account_Role__c ' + 
                      'WHERE id IN: newFinancialAccountRoles';
       return Database.getQueryLocator(query);
    }

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

        List < Financial_Account_Role__c > fARoles = (List < Financial_Account_Role__c >)scope;

        // Logic over fARoles

        List < Financial_Account__Share > listFAShares = new List < Financial_Account__Share > ();
        for (Financial_Account_role__c far: fARoles) {

            // Logic to create objects/modify data

        }

        // finally run DML
        if (listFAShares.size() > 0) {
            Database.insert(listFAShares, false);
        }
    }

    public void finish(Database.BatchableContext BC){}
}

You run your batch class with:

Database.executeBatch(new YourBatchClass(), 200)

Where '200' argument is the number of records that you'll process on per batch. Let's say that your query (Financial_Account_Role__c) returns 10200 records, then the batch class will run 'execute' method 51 times (10200/200 = 51 batches to process). Apex limits are reset for each batch, that ensures that you can process all your records without hitting Apex Limits.

  • 10200/200 = 51 batches to process. You beat me to posting my answer so I'll just nitpick yours instead ;) – smohyee Sep 7 '16 at 20:10
  • Jaja, yikes! you're right, I'll fix it, thanks for the observation. – Joca Sep 7 '16 at 20:12
  • It is happening because of Duplicate records added into the List. How can i Map listFAShares to check for duplicate values. – Samuel Jackson Sep 7 '16 at 21:18
  • @smohyee I'm surprised you didn't upvote considering it's close to the answer you would have written. – Adrian Larson Sep 7 '16 at 22:40
  • @AdrianLarson An oversight on my part. It deserves an upvote. – smohyee Sep 8 '16 at 23:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.