You need to sign in to do that
Don't have an account?
problem using future method
Hi, am running a future method in a pex class , I call this method in trigger after opportunity update, here is the trigger:
Trigger test on Opportunity(after update) {
OppDateTest.updateOppDate();
}
and here is the class and the future method am calling:
global class OppDateTest{
@future(callout=true)
public static void updateOppDate() {
Http h = new Http();
// Instantiate a new HTTP request, specify the method (GET) as well as the endpoint
String url='http://xxx.xxx.com/xxx/xxx.php';
HttpRequest req = new HttpRequest();
req.setEndpoint(url);
req.setMethod('GET');
// Send the request, and return a response
HttpResponse res = h.send(req);
String str=res.getBody();
Opportunity[] opp = [SELECT id, name FROM Opportunity where name='test'];
for (Opportunity o : opp) {
o.description = str;
update o;
}
}
}
but am getting this error whever the trigger fires:
caused by: System.DmlException: Update failed. First exception on row 0 with id 006M00000026BVNIA2; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, cloudswarm.opptySwarm: execution of AfterUpdate
caused by: System.AsyncException: Future method cannot be called from a future method: cloudswarm.SwarmHelper.evaluateOpptyRules(LIST<Id>)
(cloudswarm): []
Class.OppDateTest.updateOppDate: line 22, column 7
External entry point
Since you are updating the opportunity via this trigger, the update is firing twice - first when the record is updated by the user, and then again by the code in the trigger - so the @future is calling another @future during the seciond update.
To get round this, you need to add a boolean trigger helper, that you check when the trigger fires to see if it has already been called by this trigger.
So a simple class like this:
And then in the trigger, add an initial check for the boolean, and set to true:
Finally, set the boolean to true in the @future class...that way, the trigger won't fire when the @future updates the opportunity record.
All Answers
It looks like you've got the cloudswarm package installed, and this has added an after update trigger on the opportunity that is trying to execute an @future method of its own. As the trigger has fired from your update executed in an @future method, this fails per the apex developer's guide:
--- snip ---
You cannot call a method annotated with future from a method that also has the future annotation. Nor can you call a trigger from an annotated method that calls another annotated method.
--- snip ---
Ok I removed the cloudswarm package and still am getting the exception that I cannot call a future method froma future method? so whats the solution here? I only need to call and HTTP service after opportunity update which has to be in future method.... what can I do here?
Since you are updating the opportunity via this trigger, the update is firing twice - first when the record is updated by the user, and then again by the code in the trigger - so the @future is calling another @future during the seciond update.
To get round this, you need to add a boolean trigger helper, that you check when the trigger fires to see if it has already been called by this trigger.
So a simple class like this:
And then in the trigger, add an initial check for the boolean, and set to true:
Finally, set the boolean to true in the @future class...that way, the trigger won't fire when the @future updates the opportunity record.
Amazing !!.. that solved the issue and its working great now
Thank you very much :)