0

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 1

2

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);
}
7
  • 1
    How would I break the code into two parts since I need to make two separate http calls?? Please see my updated code. thx
    – codeSlayer
    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 }
    – Mahmood
    Dec 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..
    – codeSlayer
    Dec 9, 2014 at 10:59
  • Have you tried to debug your code? where are you getting the error, in the execute or the start?
    – Mahmood
    Dec 9, 2014 at 11:03
  • Yes I have debuged. The error is from the execute.
    – codeSlayer
    Dec 9, 2014 at 11:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .