You need to sign in to do that
Don't have an account?
Future Call limit when adding field to SOQL query (Eclipse)
Close to my wits' end on this one. I have a trigger that calls a Future class. When I run through my tests I get up to 7 future calls. I then add another conditional to my SOQL query in the trigger, and the whole thing breaks, highlighting a random line in my class and saying I'm suddenly using 11 future calls.
Trigger:
if (trigger.isInsert) { for (Contact workingContact : trigger.new) { // Check for existing Contacts List<Contact> orgContacts = [Select Id, Name, Email from Contact where ( Name = :workingContact.Name and Email = :workingContact.Email and Email != null and Id != :workingContact.Id)]; if (orgContacts.size() != 0) { NotificationEmail.AvianisError(orgContacts[0].Id, orgContacts[0].Name, 'Duplicate Contact found on Contact insert'); continue; } // Insert Contact into Avianis if (workingContact.AvianisID__c == null && workingContact.AccountId != null) { Avianis.aviContactFuture('insert', workingContact.Id); } } }
Future method called:
// Contact method @future (callout=true) public static void aviContactFuture(String operation, String conId) { // Get contact info List<Contact> sfContacts = new List<Contact>(); sfContacts = [SELECT Contact.Id, ... FROM Contact WHERE Contact.Id = :conID ALL ROWS]; if (sfContacts.size() == 0) { return; } aviContact(operation, sfContacts[0]); }
The aviContact method builds a SOAP envelope and sends it, then updates the Contact with a return value. Eclipse is highlighting a random line in the aviContact method (where it's setting a variable with "") as System.LimitException: Too many future calls: 11
In case it matters, here's the NotificationEmail.AvianisError method:
public static void AvianisError(Id EId, String EName, String ErrType) { // Send notification email if Avianis trigger encounters an error. Messaging.SingleEmailMessage mail = new Messaging.Singleemailmessage(); mail.setSaveAsActivity(false); String mailSubject = 'Avianis Trigger Error: ' + EName; String mailBody = 'Error for: ' + EName + ' https://na14.salesforce.com/' + EId + '\n\n' + 'Error Code: ' + ErrType; mail.setToAddresses(new String[] {'**@**.com'}); mail.setSubject(mailSubject); mail.setPlainTextBody(mailBody); Messaging.sendEMail(new Messaging.SingleEmailMessage[] {mail}); }
I'm going nuts here, any ideas?
Hi Chris,
You haven't mentioned whether the trigger is before or after insert. If both then it might happened that it will be processed at least two times. Whats more, if You are having some workflows which are updating the contact record then it may happened that it will be runned not once, not twice.... but even more :)
Anyway, there is a common solution for such cases. You should store along the whole transaction ids which You have processed - send for future method.
By the way I do not know your Avianis system and the API which it shares, but it will be more effficient if it could allow to send many contacts in one request and therefore process many contacts in single aviContactFuture invocation.
But lets go to the business. To preserve from processing the same record more than once you need to:
1. if You didn't do it yet, make sure that the trigger which You pasted is working on after insert (otherwise it will not make any sense, cause the contact id will be null at this stage).
2. declare in some class static map or set - it depends on Your need. Both are ok. In my example below I will use set. And for Your own comfort build 2 pasted methods:
private static Set<String> sKey;
public static boolean checkExecution(string s){
if(sKey == null || !sKey.contains(s)){
return false;
} else {
return true;
}
}
public static void markExecution(string s){
if(sKey == null){
sKey = new Set<String>();
}
sKey.add(s);
}
Then on Your trigger add code as below. It should work and block multpile future calls for the same records.
Hmm, thanks for the ideas! I implemented the change you suggested and it's still an issue but I'm working on a few different ways to try to fix it. I think the problem is stemming from my future calls updating a record, and since the future call is outside the scope of the actual operation it's totally separate from the original insert/update/etc. If I do manage to **bleep** this one I'll try to come back here and update for future Googlers.
In regards to the specifics in your post: