1

I am trying a build an integration structure for Request and Response mode. Suppose we have three SObjects, A, B, C. B is child of A and C is child of B. They all need to get integrated into a 3rd party environment via webservice callout. And in the response, it gets the external ID back and store into Salesforce.

Suppose we created three records of those Object in short amount of time, namingly we created record a, b, c. Originally I wrote the code like this:

List<A> aList = [Select Id, name, ... From A where Id in ... ];
//...
resp = http.send(req);
update aList;

List<B> bList = [Select Id, name, ... From B ...];

By using this piece of code, I am getting you have uncommitted work pending error. Haven't tried in batch environment though.

So does that mean I should put the integration of different objects into different jobs? Then how do I guarantee the execution sequence? Should I set like 1 minute interval for each job run? Or is there a better solution for this?

Edit

Maybe I didn't make it very clear at the first instance. I totally understand why I am getting this error and I am fully aware of the solution to do all the callouts first and then DML. But this is not an option in my scenario. We need to keep the same structure in our 3rd party system as in Salesforce. So without knowing the external ID which is getting back from a's web service call, b doesn't know how it should get restored in 3rd party system. So I am not quite seeing doing every callouts in the first place as an option here - unless I keep all of them just in the memory without doing the DML.

0

The error you get is because you do a callout after DML (in this case - saving object A).

What you need to do is simple - do all the callouts while keeping all objects in heap. Once you finish - do all the DML operations.

  • I know why I am getting this error. But the issue is I can't do it in the way you mentioned. In our third party system, we need to keep the same structure of relationship. So without having the external Id of a, record b doesn't know how it should get stored in 3rd party system. – Lance Shi Jul 8 '16 at 3:30
  • Does it matter how the data is structured in external system? I can see that you are using update for A (means A already exist in Salesforce) do you also use update for B and C? Why don't you just do callout for A; callout for B using new data; callout for C using new data; save A; save B; save C; The only case that could prevent you - if B and C do not exist at this point. – Andrei.Z Jul 8 '16 at 3:38
  • Okay, a has a field called external_Id__c, and when I do callouts for b, I need to query that field b.A__r.external_Id__c. And before I do update a after the callout, a.external_Id__c is null. Does it make sense to you now? – Lance Shi Jul 8 '16 at 3:43
  • Yes. Why instead of query just use directly information that you got from callout, while query everything else? you are still in same context and you have data available, just not directly in object A. If you can do so, that would be the best solution, spreading it to multiple treads will be real problem. – Andrei.Z Jul 8 '16 at 3:53
  • It is possible to achieve it in the way you suggested. But it would be pain to write and structure the code though. When doing the information gathering, I have no idea whether the related A's information is database or just in the memory. So I need to query both places and it is hard to loose-coupling those separate procedures. What is the real problem you mentioned for multiple threads? – Lance Shi Jul 8 '16 at 4:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.