【Salesforce】SObjectをクリアする
SalesforceのApex処理で、SObjectをIdのみ残して更新する処理がありました。
しかし、その処理に関連する部分で不具合が起きていたのです。
実際にSObjectをUPDATEをしているのですが、項目は更新されていませんでした。
処理のイメージとしてはこんな感じです。
public void clearAccount(Account acc){
// 更新しない項目の保持用
Account copyAcc = acc.clone(true, true);
// 取引先を初期化する
acc = new Account();
// 更新しない項目を設定する
acc.Id = copyAcc.Id;
acc.Name = copyAcc.Name;
// 取引先を更新する
update acc;
}
当たり前ではあるのですが、意図した通りには動きません。
確かにインスタンスを作成することでクリアされたようには見えるのですが、実際に更新されるのは明示的に値を設定した項目だけなんですよね。
修正してみました。
public void clearAccount(Account acc){
// 値が設定されている項目と値のMapを取得する
Map<String, Object> fieldsToValue = acc.getPopulatedFieldsAsMap();
// 値が設定されている項目にnullを設定する
for(String fieldName : fieldsToValue.keySet()){
// IDの場合は上書きしない
if('Id'.equals(fieldName)){
continue;
}
acc.put(fieldName, null);
}
// 取引先を更新する
update acc;
}
SObjectクラスにはgetPopulatedFieldsAsMapというメソッドがあります。
このメソッドは、SObjectのインスタンスに設定されている値と項目のMapを返してくれます。
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_sobject.htm
SOQLでクリアする項目をすべて取得し、このメソッドを使用して取得した項目にnullを設定すれば良いわけですね。
注意しなければいけないのは、取得してない項目はクリアされないことと、必須入力・nullを設定できない項目でしょうか。
クリアする項目が決まっているのであれば普通にnullを設定して保存した方が早いような気がしなくもないです。
実は、この不具合を解決するのに1日かかったりしています。
そのほとんどの時間がこのメソッドが原因と特定するためなのですが、削除処理があんな深くに記述されているとは思いませんでした。
No comments.