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
dave_mwidave_mwi 

DML rate limit exceeded at 21?

I'm stumped about rate limits in my Trigger. Here is the code:

Code:
trigger campaignAssociationLeadTrigger on Lead(after insert, after update){
 // Get the campaign object based on the hitbox identifier
 List<Campaign> camps = new Campaign[0];
 
 // Iterate through the 'new' list in the Trigger, which is Lead objects. This is for 'Update' of a Lead
 try
 {
  if(Trigger.isUpdate)
  {
   for(Lead l : Trigger.new)
   {
    
    // The only time we don't want to create a campaign or conversion is when
    // The old values match the incoming values. At least for now.
    boolean oldMatchSource = true;
    boolean oldMatchConversion = true;
    if(Trigger.oldMap.get(l.id) != null)
    {
     Lead oldLead = Trigger.oldMap.get(l.id);
     oldMatchSource = (l.Hitbox_Code__c != oldLead.Hitbox_Code__c);
     oldMatchConversion = (l.Conversion__c != oldLead.Conversion__c);
    }
    
    if(oldMatchSource && l.Hitbox_Code__c != null && l.Hitbox_Code__c != '')
    {
     // Get the campaing code by that name.
     try
     {
      camps.add([SELECT id FROM campaign WHERE name = :l.Hitbox_Code__c]);
     }
     catch(Exception e)
     {
      Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
      String[] toAddresses = new String[] {'me@mydomain.com'}; 
      mail.setToAddresses(toAddresses);
      mail.setSubject('Apex Exception in campaignAssociationContactTrigger');
      mail.setPlainTextBody(e.getMessage()+'\n\n'+e.getCause()+'\n\nCode was: '+l.Hitbox_Code__c);
      Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail }); 
     }
     
     // Create a campaign member from the first in the list
     if(camps.size()>0)
     {
      CampaignMember cmp = new CampaignMember(LeadId=l.id,CampaignId=camps[0].id);
      // Insert
      insert cmp;
     }
    
    }
    
    if(oldMatchConversion && l.Conversion__c != null && l.Conversion__c != '')
    {
     
     // If there was a hitbox code, add it to the conversion.
     if(camps.size()>0)
     {
      Conversion__c conv = new Conversion__c(Lead__c=l.id, Name=l.Conversion__c, Campaign__c = camps[0].id);
      insert conv;
     }
     else
     {
      Conversion__c conv = new Conversion__c(Lead__c=l.id, Name=l.Conversion__c);
      insert conv;
     }
    }
   }
  } 
  else
  {
   // This is an Insert trigger
   for(Lead l : Trigger.new)
   {
    // If there is a lead source code continue to add a campaign.
    if(l.Hitbox_Code__c != null && l.Hitbox_Code__c != '')
    {
     // Get the campaing code by that name.
     try
     {
      camps.add([SELECT id FROM campaign WHERE name = :l.Hitbox_Code__c]);
     }
     catch(Exception e)
     {
      Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
      String[] toAddresses = new String[] {'me@mydomain.com'}; 
      mail.setToAddresses(toAddresses);
      mail.setSubject('Apex Exception in campaignAssociationContactTrigger');
      mail.setPlainTextBody(e.getMessage()+'\n\n'+e.getCause()+'\n\nCode was: '+l.Hitbox_Code__c);
      Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail }); 
     }
     
     // Create a campaign member from the first in the list
     if(camps.size()>0)
     {
      CampaignMember cmp = new CampaignMember(LeadId=l.id,CampaignId=camps[0].id);
      // Insert
      insert cmp;
     }
    }
    // If the conversion is not empty, then create a conversion object
    if(l.Conversion__c != null && l.Conversion__c != '')
    {
     // If there was a hitbox code, add it to the conversion.
     if(camps.size()>0)
     {
      Conversion__c conv = new Conversion__c(Lead__c=l.id, Name=l.Conversion__c, Campaign__c = camps[0].id);
      insert conv;
     } 
     else
     {
      Conversion__c conv = new Conversion__c(Lead__c=l.id, Name=l.Conversion__c);
      insert conv;
     }
    }
   } 
  }
 }
 catch(Exception e)
 {
  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
  String[] toAddresses = new String[] {'me@mydomain.com'}; 
  mail.setToAddresses(toAddresses);
  mail.setSubject('Apex Exception in campaignAssociationContactTrigger');
  mail.setPlainTextBody(e.getMessage()+'\n\n'+e.getCause());
  Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
 }
}

 
I know the code might not be the 'soundest' but why am I exceding my limit at 21? What's happening now is that I have leads created now with incomplete campaign member or conversion object assocations. The rate can be exceeded at any one of the DML statements above...whichever happens to be 21...

If someone could point me in a good direction here or give me some good advice I would whole-heartedly appreciate it. Thanks.

- Dave

Ron HessRon Hess
Think Bulk

example link here:
http://wiki.apexdevnet.com/index.php/LeadDuplicatePreventer.apex

a useful first step is to pull all the queries outside the outermost for loop.

instead loop across tirgger.new and gather all the
Hitbox_Code__c's

into a list, then use a single query like:

[SELECT id FROM campaign WHERE name in :myHitBoxList]


do this also for insert statements, gather a list of
CampaignMember
then insert all at once
dave_mwidave_mwi

Ron,

 

Thanks. This was something that I was mulling over after making this post...I will try it out and thanks much for your response.

Thanks.

dave_mwidave_mwi
Ron, here is my altered trigger. Did I catch your drift?
 
Code:
trigger campaignAssociationLeadTrigger on Lead(after insert, after update)
{
 // Some lists to gather preliminary information.
 List<Campaign> campList = new Campaign[0];
 List<String> hitBoxList = new String[0];
 
 // Make lists for Bulk DML operations
 List<CampaignMember> campaignMemberList = new CampaignMember[0];
 List<Conversion__c> conversionList = new Conversion__c[0];
 
 // Make a map of campaign names to ids
 Map<String, String> campaignMap = new Map<String, String>();
 
 // String to hold unknown campaign codes.
 string unknownCampaignCodes = '';
 
 try
 {
  // Put hitbox codes into a String list
  for(Lead l : Trigger.new)
  {
   if(l.Hitbox_Code__c != null && l.Hitbox_Code__c != '')
   { 
    hitBoxList.add(l.Hitbox_Code__c);
   }
  }
  
  // Get all of the Campaigns in one statement, and put them into a map
  if(hitBoxList.size()>0)
  {
   campList.add([SELECT name, id FROM campaign WHERE name in:hitBoxList]);
   if(campList.size()>0)
   {
    for(Campaign currentCampaign : campList)
    {
     campaignMap.put(currentCampaign.name, currentCampaign.id);
    }
   }
  }
  
  
  if(Trigger.isUpdate)
  {
   for(Lead l : Trigger.new)
   {
    
    // The only time we don't want to create a campaign or conversion is when
    // The old values match the incoming values. At least for now.
    boolean oldMatchSource = true;
    boolean oldMatchConversion = true;
    if(Trigger.oldMap.get(l.id) != null)
    {
     Lead oldLead = Trigger.oldMap.get(l.id);
     oldMatchSource = (l.Hitbox_Code__c != oldLead.Hitbox_Code__c);
     oldMatchConversion = (l.Conversion__c != oldLead.Conversion__c);
    }
    
    if(oldMatchSource && l.Hitbox_Code__c != null && l.Hitbox_Code__c != '')
    {
     // Create a campaign member from the first in the list
     if(campaignMap.get(l.Hitbox_Code__c) != null)
     {
      CampaignMember cmp = new CampaignMember(LeadId=l.id,CampaignId=campaignMap.get(l.Hitbox_Code__c));
      campaignMemberList.add(cmp);
     }
     else
     {
      unknownCampaignCodes += 'Campaign Code was: '+l.Hitbox_Code__c+'\n\n';
     }
    }
    
    if(oldMatchConversion && l.Conversion__c != null && l.Conversion__c != '')
    {
     
     // If there was a hitbox code, add it to the conversion.
     if(campaignMap.get(l.Hitbox_Code__c) != null)
     {
      Conversion__c conv = new Conversion__c(Lead__c=l.id, Name=l.Conversion__c, Campaign__c = campaignMap.get(l.Hitbox_Code__c));
      conversionList.add(conv);
     }
     else
     {
      Conversion__c conv = new Conversion__c(Lead__c=l.id, Name=l.Conversion__c);
      conversionList.add(conv);
     }
    }
   }
  } 
  else
  {
   // This is an Insert trigger
   for(Lead l : Trigger.new)
   {
    // If there is a lead source code continue to add a campaign.
    if(l.Hitbox_Code__c != null && l.Hitbox_Code__c != '')
    {
     // Create a campaign member from the first in the list
     if(campaignMap.get(l.Hitbox_Code__c) != null)
     {
      CampaignMember cmp = new CampaignMember(LeadId=l.id,CampaignId=campaignMap.get(l.Hitbox_Code__c));
      campaignMemberList.add(cmp);
     }
     else
     {
      unknownCampaignCodes += 'Campaign Code was: '+l.Hitbox_Code__c+'\n\n';
     }
    }
    // If the conversion is not empty, then create a conversion object
    if(l.Conversion__c != null && l.Conversion__c != '')
    {
     // If there was a hitbox code, add it to the conversion.
     if(campaignMap.get(l.Hitbox_Code__c) != null)
     {
      Conversion__c conv = new Conversion__c(Lead__c=l.id, Name=l.Conversion__c, Campaign__c = campaignMap.get(l.Hitbox_Code__c));
      conversionList.add(conv);
     } 
     else
     {
      Conversion__c conv = new Conversion__c(Lead__c=l.id, Name=l.Conversion__c);
      conversionList.add(conv);
     }
    }
   } 
  }
  
  // Now run DML statements on our Lists.
  if(campaignMemberList.size()>0)
  {
   insert campaignMemberList;
  }
  if(conversionList.size()>0)
  {
   insert conversionList;
  }
  if(unknownCampaignCodes != '')
  {
   Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
   String[] toAddresses = new String[] {'me@mydomain.com'}; 
   mail.setToAddresses(toAddresses);
   mail.setSubject('Apex Warning campaignAssociationLeadTrigger - Unknown campaigns found');
   mail.setPlainTextBody(unknownCampaignCodes);
   Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
  }
 }
 catch(Exception e)
 {
  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
  String[] toAddresses = new String[] {'me@mydomain.com'}; 
  mail.setToAddresses(toAddresses);
  mail.setSubject('Apex Exception in campaignAssociationContactTrigger');
  mail.setPlainTextBody(e.getMessage()+'\n\n'+e.getCause());
  Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
 }
}

 
Ron HessRon Hess
Yes, this is a job well done, you can test this by uploading a batch of 200 lead records, or you can
even write a testMethod that creates an array of 200 new leads and then inserts them. 
You should have no DML error from that process

you may also be able to use this handy feature in the future:

Creating Maps From sObject Arrays
Maps from an ID or String data type to an sObject can be initialized from a list of sObjects. The IDs of the objects (which
must be non-null and distinct) are used as the keys. One common usage of this map type is for in-memory "joins" between
two tables. For instance, this example loads a map of IDs and Contacts:

Map<ID, Contact> m = new Map<ID, Contact>([select id, lastname from contact])

In the example, the SOQL query returns a list of contacts with their id and lastname fields. The new() method uses the
list to create a map. For more information, see SOQL Queries on page 50.
dave_mwidave_mwi
Ah!

I was searching for that in the docs as I expected that there was a way to accomplish that.

Thanks for the input!

Dave