MIXED_DML_OPERATION


[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめA～M](https://qiita.com/Keiji_otsubo/items/f3ddedee6793bf1576f8)



+ [連絡先レコードを更新し、フローを介して権限セットを割り当てる方法は？](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000HBpx9)


# System.DmlException: Insert failed. First exception on row 0; first error: MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): PermissionSetAssignment,

まぁ、たまに悩む。違うユーザで実行するのが定石かな。

[User with custom permission on their permission set is enable to perform the update](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000FTxnQ)

コメントを読んでも何をしたかはよく分からん。

I was able to get rid of the Mixed DML error, below is my final code, user with the custom permission should be able to update the opportunity which is not working as of now in my case. The scenario works perfectly when I do it on the UI.
混合DMLエラーを取り除くことができました。以下は私の最終的なコードです。カスタム権限を持つユーザーは、私の場合、現在機能していない商談を更新できるはずです。 UIで実行すると、シナリオは完全に機能します。

# Flow

+ [Auto Add Chatter Group Members to Public Group!](https://automationchampion.com/2022/04/17/auto-add-chatter-group-members-to-public-group-3/)
+ [How to Fix MIXED DML Operation Error](https://automationchampion.com/2022/04/17/how-to-fix-mixed-dml-operation-error-2/)
+ [【質問】Problem using flow to add Community User to Chatter Groups](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Pjqzs)
+ [解答例Flow to Create Contact Record from User Record](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000PfAu0SAF)

:::note
As for the MIXED_DML_OPERATION error, this occurs when you try to perform DML operations on setup objects (such as User) and non-setup objects (such as Contact) in the same transaction. To avoid this error, you need to use asynchronous actions in your flow, such as scheduled actions or invocable actions.

Check Out: [Automate This! — Resolve Mixed DML Errors with Platform Events - Salesforce Admins](https://admin.salesforce.com/blog/2022/automate-this-resolve-mixed-dml-errors-with-platform-events)

As to the best flow. Keep it simple, use a Record Trigger Flow, and make sure you are selecting One for How many records you want to create.  
:::

+ [about error : MIXED_DML_OPERATION](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007F2vOQSAZ)

:::note
I solved!! I  changed the path to Asychoronusly
:::

# テストクラスでのエラー

久しぶりに古いApex classに機能を追加したのでテストを実行したら... 確かに数年前は問題なかったのに...

:::note alert
System.DmlException: Insert failed. First exception on row 0; first error: MIXED_DML_OPERATION, 非設定オブジェクトを更新した後の設定オブジェクト上の DML 操作 (またはその逆) は、許可されていません: fkd_Property__c、元のオブジェクト: User: []
:::

+ [テストメソッドでの混合 DML 操作](https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_dml_non_mix_sobjects_test_methods.htm)

:::note
データ操作言語 (DML) 操作を実行するコードが System.runAs メソッドブロックで囲まれている場合は、テストメソッドで設定の sObject と設定以外の sObject を含む混合 DML 操作の実行が許可されます。また、テストメソッドがコールする非同期ジョブで DML も実行できます。たとえば、こうした方法を使用して、ロールのあるユーザーとその他の sObject を同じテスト内で作成できます。
:::

あああ、そういえば何か仕様が変わったような。


ダメな例
見積情報登録がSystem.runAs(u){の外側にある

```Java
        // 事前準備
        User u = fkd_User.createTestUser();
        // 見積情報登録
        fkd_Property__c fkdPro01 = new fkd_Property__c(Name='CT_TEST2_01',
//        purchase_order_number__c='',
        tantoc__c=''
        );
        insert fkdPro01;

        // テスト実施
        Test.startTest();
            // 作成したユーザで処理を実行
            System.runAs(u){
                try {
                    // インスタンス化させたくないのであれば、コンストラクタはprivate宣言しておいた方が良いはず…
                    //Cls_EstimateCapture.csv(fkdPro01.Id, selectVal, capType);//旧
                    Cls_EstimateCapture fkdOMCls = new Cls_EstimateCapture();
                    fkd0002form.ResponseDto dto = Cls_EstimateCapture.csv(fkdPro01.Id, result, capType,item_type);//新
                    System.debug('★正常終了★');
                } catch(Exception e) {
                    System.debug('error ' + e.getMessage());
                }
            }
        Test.stopTest();
```

エラーが解消できた例
見積情報登録がSystem.runAs(u){の内側にある

```Java
        // 事前準備
        User u = fkd_User.createTestUser();
        // テスト実施
        Test.startTest();
        
            // 作成したユーザで処理を実行
            System.runAs(u){
                try {
                    // 見積情報登録
                    fkd_Property__c fkdPro01 = new fkd_Property__c(Name='CT_TEST2_01',
                                                                   //        purchase_order_number__c='',
                                                                   tantoc__c=''
                                                                  );
                    insert fkdPro01;
                    // インスタンス化させたくないのであれば、コンストラクタはprivate宣言しておいた方が良いはず…
                    //Cls_EstimateCapture.csv(fkdPro01.Id, selectVal, capType);//旧
                    Cls_EstimateCapture fkdOMCls = new Cls_EstimateCapture();
                    fkd0002form.ResponseDto dto = Cls_EstimateCapture.csv(fkdPro01.Id, result, capType,item_type);//新
                    System.debug('★正常終了★');
                } catch(Exception e) {
                    System.debug('error ' + e.getMessage());
                }
            }
        Test.stopTest();
```