Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I have a business logic as follows.

1. A web service class parses XML file containing case data and loads the case to SF.
2. Trigger that on update of case email field make a call to future method to generate attachment ,send email and update case owner field.

trigger CaseUpdate on Case (After update) 
{ 
for(case c : trigger.old)
 {
    for(case ca : trigger.new)
    {
        if((c.Email__c != ca.Email__c) && (c.CS_ID__c != null) && (c.Count__c == 1))
        {
          UtilsClass.generateReport_Future(c.id);
        }
    }
 }
}


 @Future(callout=true)
 public static void generateReport_future(String caseId)
 {
String result = '';
result = generateReport(caseId);
if(result == '') 
{ 
   result = emailReport(caseId);
}
UtilsClass.ChangeOwner(caseId);

}

The issue i am facing is, System.LimitException: Too many future calls: 11, even though single case record is loaded.

Multiple records may be loaded at the same time, but they are sequential(One By One).

Are the records coming in a single batch even though they are being loaded individually..?

share|improve this question
1  
Even if that's true, you should be bulkifying your trigger anyways. –  dphil Jun 6 at 15:14
    
Hi dphil, can u pls help me up with how bulkifying the trigger will help overcome the exception...it will be a great help....! i would like to know before implementing .thanks –  Bharadwaj Urma Jun 6 at 15:34
    
The exception occurs because your trigger isn't bulkified. If it was bulkified, you would only need to make 1 future call instead of 1 for each object added. –  dphil Jun 6 at 19:28

1 Answer 1

up vote 8 down vote accepted

The governor limit is that no more than 10 future calls may be made in a single request so your trigger is broken as soon as more than 10 Case objects are updated at once that match you if condition.

If you want to use a future method call it once and pass it the set of case IDs i.e. collect the set if IDs first then make a single call to the future method.

Add debugging to your trigger to see how many Case objects are coming through at once if you are not sure. But the trigger needs bulkifying anyway.

Note that if you are using this sort of code in other triggers and those triggers run as part of the same request their future method calls will also be counted so they all need bulkifying.

PS

Noticed your trigger has an unnecessary nested loop pattern. This would be a typical way to accomplish what I think you are trying to do:

trigger CaseUpdate on Case (After update) {
    Set<Id> ids = new Set<Id>();
    for(Case c : Trigger.new) {
        Case old = Trigger.oldMap.get(c.Id)
        if (c.Email__c != old.Email__c && c.CS_ID__c != null && c.Count__c == 1) {
            ids.add(c.Id);
        }
    }
    if (ids.size() > 0) {
        // Change the future method to take a set of IDs
        UtilsClass.generateReport_Future(uds);
    }
}

PPS

If the web service API you are calling only allows a request for a single Case to be made at once (and can't be changed) you can use a Batchable marked with Database.AllowsCallouts and set the batch size to 10 instead of the future. But there are governor limit traps there too to watch out for (that will be eased when the "Apex Flex Queue" eventually becomes generally available).

share|improve this answer
    
The question coming to my mind is...if there are more than 10 records being updated once, making 10+ future calls, so there are 10+ callouts being made. correct me if i am wrong , but Bulkifying the trigger will only stop future call exception. Callouts exception may come up since 10+ callouts will be made anyhow. –  Bharadwaj Urma Jun 6 at 16:01
    
@BharadwajUrma Yes you are right the same need for bulkification applies there. If the callout API allows multiple requests to be made at once go ahead and do that and the problem is solved (as you only consume 1 of the available 10 requests). If it doesn't then you may have to resort to using a Batchable (to work through the calls 10 per execute method) which adds complexity. –  Keith C Jun 6 at 16:04
    
is this possible.."records come in a single batch even though they are being loaded individually" –  Bharadwaj Urma Jun 6 at 16:10
    
@BharadwajUrma If each incoming record is truly in separate transaction then your trigger should only see one record at a time. I suggest you add debug logging to find out what is going on in your trigger rather than assume. But do not leave your trigger unbulkified because sooner or later someone will do an update that causes the governor limit to be hit and that will make you an unpopular person... –  Keith C Jun 6 at 16:17
    
@Keith..Thanks for Your support. i will implement Yours idea and will update you..will reach u if issue still exists....! –  Bharadwaj Urma Jun 6 at 16:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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