Apex トリガーを使用した変更イベントへの登録
学習の目的
この単元を完了すると、次のことができるようになります。
- Apex トリガーを記述して変更イベントに登録する。
- Salesforce で更新を行い、変更イベント通知を生成する。
- デバッグログのトリガーからデバッグログメッセージを検証する。
ここまでに、Pub/Sub API を使用して変更イベントに登録する方法を学習しました。Apex トリガーは、変更イベントに登録するもう 1 つの方法です。では、詳しく見ていきましょう。
変更イベントの非同期 Apex トリガー
Apex トリガーを使用して、Lightning プラットフォームの変更イベントに登録できます。変更イベントの Apex トリガーは Salesforce オブジェクトの Apex トリガーと似ていますが、いくつかの点が異なります。Salesforce オブジェクトの Apex トリガーと同様に、Salesforce オブジェクトに対応する変更イベントに変更イベントトリガーを定義します。after insert トリガーのみがサポートされています。
変更イベントトリガーは、変更イベントに after insert
キーワードを指定し、次の形式で定義します。
trigger TriggerName on ChangeEventName (after insert) { }
AccountChangeEvent オブジェクトの例を次に示します。これは、取引先に対応する変更イベントです。
trigger MyAccountChangeTrigger on AccountChangeEvent (after insert) { }
1 つの変更イベントまたは変更イベントのバッチを受信すると、変更イベントトリガーが起動します。変更イベントトリガーは、オブジェクトトリガーとは異なり、データベーストランザクションの完了後に非同期で実行されます。変更イベントトリガーは非同期で実行されるため、大量のリソースを消費するビジネスロジックに適しています。他方、トランザクションベースのロジックは引き続きオブジェクトトリガーで実行します。変更イベントトリガーでは、変更の処理を分離することでトランザクションの処理時間を短縮できます。
変更イベントトリガーには、次の特性があります。
- 自動化プロセスエンティティの下で実行される。そのため、トリガーのデバッグログが自動プロセスエンティティによって作成され、CreatedById や OwnerId などのシステム項目が自動プロセスを参照します。
- Apex 非同期ガバナ制限が適用される。
- 最大バッチサイズはイベントメッセージ 2,000 件 (
Trigger.New
の項目数) である。
Apex 変更イベントのレコード項目とヘッダー項目
変更イベントメッセージの項目は静的に定義されるため、他の Apex 型と同様に、すべてのレコード項目が記載されます。Apex 変更イベントメッセージには空 (null) の項目も記載できます。null になるのは、変更のない項目と、更新で明示的に null に設定された項目です。
どの項目が変更されたかを知るには、changedFields
ヘッダー項目を使用します。これには、更新操作で変更されたレコード項目のリストが含まれています。この単元のトリガーの例では、changedFields 項目を使用して、どの項目が更新または削除されたのかを判断する方法を示します。
変更イベントトリガーの作成
変更イベントトリガーを追加する手順は、Salesforce オブジェクトにトリガーを追加するのと同じくらい簡単です。開発者コンソールを使用して、以前に作成した Employee (従業員) カスタムオブジェクトに関連付けられている変更イベントのトリガーを作成します。カスタムオブジェクトの作成時に、Employee__ChangeEvent という変更イベントオブジェクトが作成されます。
開発者コンソールを使用して変更イベントトリガーを作成する手順は、次のとおりです。
- クイックアクセスメニュー () をクリックします。
-
[開発者コンソール] をクリックします。
- 開発者コンソールで、[File (ファイル)] | [New (新規)] | [Apex Trigger (Apex トリガー)] を選択します。
- [Name (名前)] 項目に、
EmployeeChangeTrigger
というトリガーの名前を入力します。
- ドロップダウンから、Employee (従業員) カスタムオブジェクトの変更イベントオブジェクト (Employee__ChangeEvent) を選択します。
after insert
キーワードを指定したトリガーが作成されます。
- デフォルトのコンテンツを次のコードに置き換えます。
trigger EmployeeChangeTrigger on Employee__ChangeEvent (after insert) { List<Task> tasks = new List<Task>(); // Iterate through each event message. for (Employee__ChangeEvent event : Trigger.New) { // Get some event header fields EventBus.ChangeEventHeader header = event.ChangeEventHeader; System.debug('Received change event for ' + header.entityName + ' for the ' + header.changeType + ' operation.'); // For update operations, we can get a list of changed fields if (header.changetype == 'UPDATE') { System.debug('List of all changed fields:'); for (String field : header.changedFields) { if (null == event.get(field)) { System.debug('Deleted field value (set to null): ' + field); } else { System.debug('Changed field value: ' + field + '. New Value: ' + event.get(field)); } } } // Get record fields and display only if not null. System.debug('Some Employee record field values from the change event:'); if (event.First_Name__c != null) { System.debug('First Name: ' + event.First_Name__c); } if (event.Last_Name__c != null) { System.debug('Last Name: ' + event.Last_Name__c); } if (event.Name != null) { System.debug('Name: ' + event.Name); } if (event.Tenure__c != null) { System.debug('Tenure: ' + event.Tenure__c); } // Create a followup task Task tk = new Task(); tk.Subject = 'Follow up on employee record(s): ' + header.recordIds; tk.OwnerId = header.CommitUser; tasks.add(tk); } // Insert all tasks in bulk. if (tasks.size() > 0) { insert tasks; } }
Trigger.New
で変更イベントメッセージを受信するたびにこの変更イベントトリガーが反復処理されます。イベントごとに、トリガーがいくつかのヘッダー項目を取得します。操作が更新の場合は、トリガーが nulledFields
ヘッダー値にアクセスして、変更された項目のリストも取得します。null でない場合は、トリガーにレコード項目値が表示されます。最後に、新しい Employee (従業員) レコードのフォローアップ ToDo が作成されます。
変更イベントトリガーの実行の検証
ここで、トリガーが機能していることを手動で検証します。トリガーでイベントメッセージを受信するには、まず [設定] の [変更データキャプチャ] でオブジェクトを有効にします。前のステップですでに Employee (従業員) の通知を有効にしているため、ここではそのステップを省略できます。自動プロセスエンティティの下にデバッグログが作成されるので、[設定] でこのエンティティのデバッグログを有効にして、ログが収集されるようにします。
- 新しいタブで [設定] を開くには、クイックアクセスメニュー () をクリックして、[設定] をクリックします。
- [Setup (設定)] から、[Quick Find (クイック検索)] ボックスに
Debug Logs
(デバッグログ) と入力し、[Debug Logs (デバッグログ)] を選択します。
-
[新規] をクリックします。
- [追跡対象エンティティ種別] で、[自動化プロセス] を選択します。
- ログの収集期間を選択します。開始日と終了日は、デフォルトで現在の日時に設定されます。終了日入力ボックスをクリックし、カレンダーから翌日を選択して、終了日を延長します。
- [デバッグレベル] で、[新しいデバッグレベル] をクリックします。名前に
CustomDebugLevel
と入力し、デフォルトを受け入れます。
-
[Save (保存)] をクリックします。
またすぐデバッグログに戻ってくるため、[設定] の [デバッグログ] ページを開いたままにします。次に、Salesforce で何らかの変更を行って、変更イベントトリガーを起動します。Employee (従業員) レコードを作成して更新します。
- 新しいタブでアプリケーションランチャー () をクリックし、[Employees (従業員)] を見つけて選択します。
-
[新規] をクリックします。
- 次の項目に入力します。
- Employee Name (従業員名):
e-200
- Last Name (姓):
Smith
- First Name (名):
Joseph
- Tenure (在職期間):
1
-
[Save (保存)] をクリックします。
- 従業員レコードの詳細ページで、[編集] をクリックします。
- [First Name (名)] 項目を
Joe
に変更します。
- [Tenure (在職期間)] の値を削除します。
-
[保存] をクリックします。
- [デバッグログ] タブに切り替えて、ブラウザーを更新します。
- レコード作成に対応するデバッグログを表示する場合は、リストの 2 つ目のログの横にある [表示] をクリックします (ログは新しい順に並べられています)。
System.debug
ステートメントの出力は、次のようになります。
...|DEBUG|Received change event for Employee__c for the CREATE operation. ...|DEBUG|Some Employee record field values from the change event: ...|DEBUG|First Name: Joseph ...|DEBUG|Last Name: Smith ...|DEBUG|Name: e-200 ...|DEBUG|Tenure: 1.0
- レコード更新に対応するデバッグログを表示する場合は、リストの 1 つ目のログの横にある [表示] をクリックします。
System.debug
ステートメントの出力は、次のようになります。レコードが更新されると、システムが LastModifiedDate 項目を更新するため、この項目は変更された項目の一部としてリストされます。
...|DEBUG|Received change event for Employee__c for the UPDATE operation. ...|DEBUG|List of all changed fields: ...|DEBUG|Changed field value: LastModifiedDate. New Value: 2019-09-26 20:53:29 ...|DEBUG|Changed field value: First_Name__c. New Value: Joe ...|DEBUG|Deleted field value (set to null): Tenure__c ...|DEBUG|Some Employee record field values from the change event: ...|DEBUG|First Name: Joe
おめでとうございます。変更イベントトリガーを作成し、ユーザーインターフェースで正常に機能していることを確認しました。次の単元では、変更イベントトリガーの Apex テストを記述して、トリガーのテストを自動化する方法を学習します。
リソース
-
Salesforce Developers: Change Data Capture Developer Guide: Subscribe with Apex Triggers (変更データキャプチャ開発者ガイド: Apex トリガーを使用した登録)
-
Salesforce Developers: Apex 開発者ガイド