[SFDC]DML on generic List<SObject> only allowed for insert, update or delete

メモ。
Apexの「DML on generic List<SObject> only allowed for insert, update or delete」という例外の発生について。
すべてのオブジェクトは総称的に「sObject」型として表すことができますが、sObject型のListはupsertできません。上記のエラーが発生します。
insert/updateと処理を分けるか、Listの型を具体的なオブジェクトに決めてしまい、Listへの追加時にキャストする必要があります。

以下蛇足。

とあるユーティリティクラスを作った。2つのカスタムオブジェクト間で、名前が等しいカスタム項目の値をコピーしたり変換したりするというもの。

イメージとしてはこんな感じ。実際はだいぶ違うけれど。
Bulk APIで外部からデータ連携する際に、 中間テーブル > 本テーブル という構造・項目名がよく似た2つのオブジェクトに対して二段階でデータ登録することにしたが、1項目づつ値をコピーするのが面倒だったので作った。
シナリオは以下の通り。

1.Bulk API で外部から中間テーブルに対してupsertする。
2.中間テーブルの after insert/after update でトリガを起動
3.2のトリガ内で、中間テーブルのレコードを本テーブルのレコードに変換/補正して本テーブルにupsertする。

トリガ内で上述のユーティリティを使いたかった。こんな感じで。

実行するとupsert処理でエラーになる。「DML on generic List<SObject> only allowed for insert, update or delete」。ObjectConverter.convertの戻り値がList<sObject>だから?

はコンパイルエラーで

が通るので、Listの型はうまいこと変換してくれてるのかと思っていたのだけれどそんなことはなかった模様。
結局、ユーティリティからListを取り出すのはあきらめて、1レコードづつ変換して呼び出し元でいちいちキャストする方法に落ち着いた。

 

理想形はこう。

仮型引数(とついでに仮型引数からのインスタン化)がサポートされればなー


コメントを残す