I have a batch class that makes a external Http callout to create case records with a CreatePublicStuffCases() which is called in the start(). In the execute function, I have another callout to get users details for specific cases that were previously inserted in the CreatePublicStuffCases(). Then at the end, do a DML to insert new account and also, update the cases that were previously inserted with thier respective case owners. I keep getting the error "System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out". Even when I tried doing the insert outside the loop with a List DML insert. Any help is much appreciated.
1 Answer
Problem
Actually, webservice or http callouts and a DML won't take place in the same transaction. And that's why you are getting the error. Read about this problem.
Solution
- You could break your code into two parts, as per the suggestion in the above article, Webservice part and the DML part.
- Use
@Future
annotation. I had such problem and resolved using that.
Code Sameple This is just a out-of-mind code. but you need make changes or test this as per your need.
//global variable at the top
Map<String,Object> mapObject;
//start ()
execute () {
CallWebService();
Map<String,Object> rawObj = mapObject;
// Your remaining code
}
@future
public PageReference CallWebService() {
// initialize the global variable.
mapObject = new Map<String,Object>();
HttpRequest req = new HttpRequest();
req.setMethod('GET');
req.setEndpoint('https://www.publicstuff.com/api/2.0/request_view?request_id='+newReq');
Http http = new Http();
HTTPResponse res = http.send(req);
String resonseBody = res.getBody();
String jsonString = resonseBody;
mapObject = (Map<String,Object>) JSON.deserializeUntyped(jsonString);
}
-
1How would I break the code into two parts since I need to make two separate http calls?? Please see my updated code. thx Dec 9, 2014 at 10:43
-
In the
execute( )
method of your batch, you can break your http callout to another method using@future
annotation . something like@future private void newReq(){ // your http call out from execute method }
– MahmoodDec 9, 2014 at 10:51 -
The problem is, I am using the List passed from the start function to generate a unique endpoint in my http callout. If its not done this way, then I cannot update the records correctly.. Dec 9, 2014 at 10:59
-
Have you tried to debug your code? where are you getting the error, in the
execute
or thestart
?– MahmoodDec 9, 2014 at 11:03 -