[Salesforce] カスケード削除処理対象レコードに紐づくレコードをApexトリガで更新する処理で困ったこと


概要

  • こちらの記事では、カスケード削除処理対象レコードに紐づくレコードのトリガー処理実装時につまずいた点を記事にします。

取引責任者の役割(OpportunityContactRole)

今回実装したかったトリガ

  • 取引先責任者に紐づく取引先責任者の役割が紐付いている商談の積み上げ集計をトリガで実装

具体的な内容

   集計対象       = 商談: 対象フラグ(isTarget__c){true}のレコード
   集計先         = 取引先責任者: 件数(OpportunityNum__c) に積み上げ集計を行う
   集計対象の条件  = 取引先責任者が紐付いている取引先責任者の役割が参照している商談のみ

つまずいた点

  • 商談削除時に商談が紐づく取引先責任者の役割が紐づく取引先責任者を更新処理

この実装を行う際につまずいてしまいました、、、

初めに試してみた実装

1. 取引責任者に商談を集計するトリガメソッドを実装
2. 取引先責任者を空更新させて再集計させる

商談(削除)→取引先責任者(カスケード削除)→取引先責任者の役割: AfterDeleteトリガーで取引先責任者を更新

初めはうまく実装できたと思ったのですが大きな問題を見落としていました、、、

カスケード削除によってトリガ処理は実行されないのです、、、

解決するために試した方法

1. 商談削除時にAfterDeleteトリガでカスケード削除を行って削除されてレコードを取得
2. 取得したレコードから対象の取引先責任者の値を抽出し取引先責任者を更新

SOQL ステートメントは、ALL ROWS キーワードを使用して、削除されたレコードやアーカイブされた活動など、組織内のすべてのレコードを照会できます。

実装例


   private void 商談削除時取引先責任者空更新メソッド(List<Opportunity> 削除した商談リスト) {

        Set<Id> oppIdSet = new Set<Id>();
        for (Opportunity opp : 削除した商談リスト) {
            oppIdSet.add(opp.Id);
        }

        List<Contact> targetContactList = new List<Contact>();
        for (AggregateResult aggr : [
                SELECT
                    ContactId
                FROM
                    OpportunityContactRole
                WHERE
                    OpportunityId IN :oppIdSet
                    AND IsDeleted = true
                    GROUP BY ContactId
                ALL ROWS
        ]) {
            targetContactList.add(new Contact(Id = String.valueOf(aggr.get('ContactId'))));
        }
        update targetContactList;
    }

最後に

今回つまずいたことでトリガの実行されない処理などについて再確認できたのでいい勉強になりました。
Salesforceの標準機能や標準オブジェクトはまだまだ触った機会・知識が少ないので、
Salesforceエンジニアと名乗る以上、勉強に励まなければならないと痛感しました。