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

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.
The start function :
The start function :
public Database.QueryLocator start(Database.BatchableContext context) { CreatePublicStuffCases(); String ps = 'Public Stuff'; return Database.getQueryLocator('SELECT External_Source_Id__c FROM Case WHERE Requires_User_Details__c = true AND External_Source_Id__c != Null AND Origin =: ps'); }The execute function :
public void execute(Database.BatchableContext context, List<Case> scope) { //List<Account> publicStuffAccounts = new List<Account>(); for (Case cse : scope) { String newReq = cse.External_Source_Id__c; 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; Map<String,Object> rawObj = (Map<String,Object>) JSON.deserializeUntyped(jsonString); Map<String,Object> responseObj = (Map<String,Object>)rawObj.get('response'); Map<String,Object> userDetails = (Map<String,Object>) responseObj.get('user_detail'); //select a specific value String requeststatus = (String) responseObj.get('request_status'); String firstname = (String) userDetails.get('firstname'); String lastname = (String) userDetails.get('lastname'); String email = (String) userDetails.get('email'); String phone = (String) userDetails.get('phone'); String address = (String) userDetails.get('address'); String zipcode = (String) userDetails.get('zipcode'); String space = (String) userDetails.get('space'); String state = (String) userDetails.get('state'); //check Account newPublicStuffContact = new Account(LastName = lastname, FirstName = firstname, PersonEmail = email, Phone = phone, PersonMailingStreet = address, PersonMailingPostalCode = zipcode, PersonMailingState = space, PersonMailingCountry = state); if (lastname == Null){ return; } else{ try{ insert newPublicStuffContact; //publicStuffAccounts.add(newPublicStuffContact); Case caseUpdate = [SELECT Id, ContactId, Requires_User_Details__c FROM Case WHERE Id = :cse.Id]; //update and mark the case's Requires_User_Details__c as false caseUpdate.Requires_User_Details__c = false; caseUpdate.AccountId = newPublicStuffContact.Id; System.debug('The newPublicStuffContact Id : ' + newPublicStuffContact.Id); Update caseUpdate; } catch (Exception e){ System.debug('Error inserting case' + e.getMessage()) } } //mapPSContact.put(newPublicStuffContact.Id, newPublicStuffContact); } //insert publicStuffAccounts; }The CreatePublicStuffCases function :
public static void CreatePublicStuffCases() { // Callout code verbatim from the question Date d = Date.today(); JSONGenerator gen = JSON.createGenerator(true); HttpRequest req = new HttpRequest(); req.setMethod('GET'); req.setEndpoint('https://www.publicstuff.com/api/2.0/requests_list?limit=2&client_id=****&status=open'); Http http = new Http(); HTTPResponse res = http.send(req); String resonseBody = res.getBody(); String jsonString = resonseBody; Map<String,Object> rawObj = (Map<String,Object>) JSON.deserializeUntyped(jsonString); Map<String,Object> responseObj = (Map<String,Object>)rawObj.get('response'); List<Case> newCases = new List<Case>(); Map<String, Object> iMap = new Map<String, Object> (); Map<String,Object> id = new Map<String, Object>(); List<Object> reqs = (List<Object>)responseObj.get('requests'); for (Object x : reqs) { iMap = (Map<String, Object>)x; for (String field : iMap.keySet()) { id = (Map<String,Object>) iMap.get(field); String idx = 'id'; String title = 'title'; String description = 'description'; String status = 'status'; String address = 'address'; String location = 'location'; String zipcode = 'address'; Integer OId = (Integer) id.get(idx); String Otitle = (String) id.get(title); String Odescription = (String) id.get(description); String OStatus = (String) id.get(status); String Oaddress = (String) id.get(address); String OLocation = (String) id.get(location); String OZipCode = (String) id.get(zipcode); Boolean OrequiresUserDetails = true; String CaseRecordTypeId = GlobalStaticMetaDataCache.getRTId('Case', GlobalFixedParams.RECORDTYPE_CASE_SERVICE_REQUEST); Case c = new Case(recordTypeId = CaseRecordTypeId, External_Source_Id__c = String.valueOf(OId), Customer_Request_Details__c = Otitle + ' ' + Odescription, Status = OStatus, SuppliedTargetAddress__c = Oaddress + ' ' + OLocation + ' ' + OZipCode, Requires_User_Details__c = OrequiresUserDetails, Origin = 'Public Stuff'); newCases.add(c); } } try{ insert newCases; }catch (Exception e){ } }The excute function will send an email but that is no problem at the moment.
Then kick off the batch job as