You need to sign in to do that
Don't have an account?
Batch Apex, callouts and updates
I am stuck on this. I am getting the "You have uncommitted work pending. Please commit or rollback before calling out" CalloutException, even though I am doing the operations in the right order as I understand it.
The batch job has to select accounts that need updating, call a webservice to query some data, and update the accounts with this new information.
Below is a simplified version of my code. Basically:
- In the start() method I run a query on Account and return a QueryLocator
- In the execute() method I loop through the List<Account>, do as many callouts as needed and set the relevant fields in the Account objects; at the end of the loop I do one update operation.
This should preserve the rule "no not do callouts after DML operations". But the second callout after I first set the fields is failing. It seems though setting field values on the object counts as DML, even though I am not performing the update operation yet.
Does that make sense? How can it be fixed? Or is it a whole different thing that I am doing wrong?
Thanks in advance.
global class AccountsUpdateWebService implements Database.Batchable<sObject>, Database.AllowsCallouts, Database.Stateful { global Database.QueryLocator start(Database.BatchableContext bc){ String query = 'Select Id, Name FROM Account ...'; return Database.getQueryLocator(query); } global void execute(Database.BatchableContext bc, list<Account> accounts) { List<Account> toupdate = new List<Account>(); for (Account account: accounts) { // Callout to web service that retrieves address info WSData wsdata = WebService.getData (account.Name); account.BillingStreet = wsdata.Street; account.BillingPostalCode = wsdata.PostalCode; toupdate.add (accounts); } update toupdate; } global void finish(Database.BatchableContext bc) { } }
Can't you set your scope size of batch to 1 or send multiple Accounts to webservice for processing in one go and updating the records based on the response received?
Thanks,
Pankaj
All Answers
In 15th line please give toupdate.add (account);
You are adding all the accounts everytime. ---> toupdate.add (accounts);
------------
Thanks,
Srinivas
- Please mark as solution if your problem is resolved.
Please use below mentioned code:
Thank you both for your answers. Actually the line toupdate.add (accounts); was a typo when simplifying my code for posting. I double checked my actual code and I am adding just one object at a time to the list.
I am getting the same result:
- Enter the for loop
- Call web service first time
- Set fields on account object
- Call web service second time -> CalloutException
Can't you set your scope size of batch to 1 or send multiple Accounts to webservice for processing in one go and updating the records based on the response received?
Thanks,
Pankaj