使っているクラウドなどの小ネタ Advent Calendar 2024 19日目
画面のボタンからApexのクラスをコールするようにして実行すると問題なく機能します。
ただし、Apexバッチに組み込んで使うと下記のエラーになります。
You have uncommitted work pending. Please commit or rollback before calling out
まさにここで解説されているとおりの内容
なんのための制限かわかりませんが、(コールアウト実行 → 結果をリストやマップなどに保持)を繰り返す → レコード更新 とする必要があります。
最終的な対応
バッチ処理で使えるように一括処理を考慮したコードに書き直しました。
public static String calljobcan_org2(List<Jobcan053__c> j53List) {
if (j53List == null) return '';
Map<String,String> saveBodyMap = new Map<String,String>();
for (jobcan053__c j53 : j53List){
String stBody = callout_org(j53);//ここでコールアウトさせて、Jsonを得る
saveBodyMap.put(j53.Id,stBody);//Mapに保存する
}
List<Jobcan053__c> updateJ53List = new List<Jobcan053__c>();
for (jobcan053__c j53 : j53List){
String stBody = saveBodyMap.get(j53.Id);
if (stBody != null) {
//Jsonを使ってオブジェクトに値をセットする
Jobcan053__c j53new = createJobcan053(j53.Id,stBody);
updateJ53List.add(j53new);//結果はListに保存する
}
if (updateJ53List.size() >0) update updateJ53List;//一括更新
}
return '';
}
別の処理でも同じです。コールアウト結果も変数に入れて後でまとめて判断してDML操作を行います。
コールアウト⇒DML⇒コールアウトではエラーになります。
/**
* 複数件処理する。バッチからの起動用
*/
public static List<Jobcan053__c> calljobcan_org2(List<Jobcan053__c> j53List) {
List<Map<String,Object>> RetMapList = new List<Map<String,Object>>();
List<Jobcan053__c> updateJ53List = new List<Jobcan053__c>();
if (j53List == null) return updateJ53List;
for (jobcan053__c j53 : j53List){
Map<String,Object> RetMap = new Map<String,Object>();
RetMap = jobcan_callout5.callout_org3(j53);
RetMapList.add(RetMap);
}
for (Map<String,Object> rm : RetMapList) {
if ((Integer)rm.get('StatusCode') == 200){
Jobcan053__c j53n = new Jobcan053__c();
j53n.Id = (String)rm.get('Id');
j53n.isTask__c = true;
updateJ53List.add(j53n);
}
}
system.debug(Logginglevel.INFO,'size===> '+ updateJ53List.size());
//if (updateJ53List.size() >0 ) update updateJ53List;
return updateJ53List;
}