You need to sign in to do that
Don't have an account?

@future calls limit, how do I convert my trigger to be ran as a batch apex class to get around this?
Hey guys, so I have a trigger than runs whenever an address is updated or saved, to do reverse geocode and write the latitude and logitude to a field. The problem is, when a lot of records are updated at once, I run into the future call limit governer.....
See the code below: Any help is much appreciated.
that's the trigger, which then runs this apex class:
This works very well, until you try to update a lot of records at once....when you do you run into the @future calls limit.
I had read that using a batch apex class can solve this, any advice on how to do that is appreciated.
I had posted a previous thread where another developer suggested I use a list to get around this, and it seemed to work, but after testing it, it broke the writing of geocode to the location field. See this thread: https://developer.salesforce.com/forums/ForumsMain?id=906F0000000B2h8IAC
See the code below: Any help is much appreciated.
/*// Trigger runs getLocation() on Accounts with no Geolocation trigger SetGeolocation on Account (after insert, after update) { for (Account a : trigger.new) if (a.Location__Latitude__s == null) LocationCallouts.getLocation(a.id); }*/ // Trigger runs getLocation() on Accounts with no Geolocation trigger SetGeolocation on Account (after insert, after update) { for (Account a : trigger.new){ if(system.isFuture() == FALSE){ LocationCallouts.getLocation(a.id); } } }
that's the trigger, which then runs this apex class:
public class LocationCallouts { @future (callout=true) // future method needed to run callouts from Triggers static public void getLocation(id accountId){ // gather account info Account a = [SELECT BillingCity,BillingCountry,BillingPostalCode,BillingState,BillingStreet FROM Account WHERE id =: accountId]; // create an address string String address = ''; if (a.BillingStreet != null) address += a.BillingStreet +', '; if (a.BillingCity != null) address += a.BillingCity +', '; if (a.BillingState != null) address += a.BillingState +' '; if (a.BillingPostalCode != null) address += a.BillingPostalCode +', '; if (a.BillingCountry != null) address += a.BillingCountry; address = EncodingUtil.urlEncode(address, 'UTF-8'); // build callout Http h = new Http(); HttpRequest req = new HttpRequest(); req.setEndpoint('http://maps.googleapis.com/maps/api/geocode/json?address='+address+'&sensor=false'); req.setMethod('GET'); req.setTimeout(60000); try{ // callout HttpResponse res = h.send(req); // parse coordinates from response JSONParser parser = JSON.createParser(res.getBody()); double lat = null; double lon = null; while (parser.nextToken() != null) { if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) && (parser.getText() == 'location')){ parser.nextToken(); // object start while (parser.nextToken() != JSONToken.END_OBJECT){ String txt = parser.getText(); parser.nextToken(); if (txt == 'lat') lat = parser.getDoubleValue(); else if (txt == 'lng') lon = parser.getDoubleValue(); } } } // update coordinates if we get back if (lat != null){ a.Location__Latitude__s = lat; a.Location__Longitude__s = lon; update a; } } catch (Exception e) { } } }
This works very well, until you try to update a lot of records at once....when you do you run into the @future calls limit.
I had read that using a batch apex class can solve this, any advice on how to do that is appreciated.
I had posted a previous thread where another developer suggested I use a list to get around this, and it seemed to work, but after testing it, it broke the writing of geocode to the location field. See this thread: https://developer.salesforce.com/forums/ForumsMain?id=906F0000000B2h8IAC
Instead of getLocation(id accountId), rewrite your future method to take list of Ids
getLocation(List<id> accountIds)
Check if your callout endpoint (Google API) can take multiple address in a single request.
else make sure that you pass max of 100 ids to your future methods.
below are the Governer limits you should consider.
Total number of callouts (HTTP requests or Web services calls) in a transaction 100
Maximum number of methods with the future annotation allowed per Apex invocation 50