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
Dman100Dman100 

Error: Too man DML statements

I have a trigger, which has been working fine for several months in our production org and the last two days I recieved the following error message:
 
setCriticalAccountTrue: execution of AfterUpdate
caused by: System.Exception: Too many DML statements: 21
Class.CriticalAccount.setCriticalAccountTrue: line 16, column 9
Trigger.setCriticalAccountTrue: line 2, column 5
 
Is the error getting caused because the trigger is not handling bulk updates?
 
Here is the trigger code and class:
 
Code:
trigger setCriticalAccountTrue on Case (after update) {
 CriticalAccount.setCriticalAccountTrue(Trigger.new);
}



public class CriticalAccount {
 
 public static void setCriticalAccountTrue(Case[] cases) {
  
  List<Account> acctList = new List<Account>();
  
  for (Case c : cases) {
   
   if(c.Priority == 'Critical') {
   
   Account a = new Account( Id = c.AccountId );
      a.Critical_Account__c = true;

      acctList.add(a);
  }
  update acctList;
  }
 }
 
 public static testMethod void testCriticalAccountClass() {
  // Create a new case to test
  Case c = new Case(RecordTypeId='01230000000DCKS',
Type='Remediation',Reason='Miscellaneous',Subject='test',
Status='New',Priority='High',Origin='Email',ContactId='0033000000J6B9Y',
AccountId='0013000000BfAg4',Description='test'); insert c; // Update the case status to 'Working' and case priority to 'Critical' c.Status='Working'; c.Priority='Critical'; update c; // Check if critical account field has been set to true System.assert(true, [Select a.Critical_Account__c from Account a WHERE a.Id = '0013000000BfAg4'].Critical_Account__C); } }

 
Thanks for any help.
 
Joseph FerraroJoseph Ferraro
i would try gathering all the account ids related to the cases in a set, then iterate the set of accounts, set the values you need, add the accounts to a list and update the list.  I'm not sure whether this is the solution, but you could give it a try.  Also, are you using production account and contact records in your test method? 

Code:
Set<Id> myAccountIds = new Set<Id>();
for (Case c : cases)
{
  if (c.priority == 'Critical')
  {
    myAccountIds.add(c.accountid);
  }
}

List<Account> myAccounts = new List<Account>();

for (Account a : [select id from account where id in :myAccountIds])
{
  a.critical_account__c = true;
  myAccounts.add(a);
} update myAccounts;

 

Joseph FerraroJoseph Ferraro
actually, are you sure you don't have a series of triggers running?
Ron HessRon Hess
your update statement is inside the loop on cases, so will not handle bulk operations properly

one change may help

try this :
Code:
public class CriticalAccount {
 
 public static void setCriticalAccountTrue(Case[] cases) {
  
  List<Account> acctList = new List<Account>();
  
  for (Case c : cases) {
   
   if(c.Priority == 'Critical') {
   
    Account a = new Account( Id = c.AccountId );
      a.Critical_Account__c = true;

      acctList.add(a);
   } 
  }
  
  update acctList;  // only done once
  
 }

 

Joseph FerraroJoseph Ferraro
Ron: good call, totally missed that.