[SalesForce] Apex Batch : You have uncommitted work pending. Please commit or rollback before calling out

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.

Best 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

  1. You could break your code into two parts, as per the suggestion in the above article, Webservice part and the DML part.
  2. 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);
}
Related Topic