كيفية تجنب خطأ mixed_dml_operation في اختبارات Salesforce التي تنشئ المستخدمين

StackOverflow https://stackoverflow.com/questions/2387475

سؤال

في بعض الأحيان في اختبارات Salesforce ، تحتاج إلى إنشاء كائنات مستخدم لتشغيل جزء من الاختبار كنوع من المستخدمين.

ومع ذلك ، منذ تحديث Salesforce Summer 08 ، يحاول إنشاء كائنات المستخدم والكائنات العادية (مثل الحسابات) في نفس الاختبار يؤدي إلى الخطأ التالي:

mixed_dml_operation ، لا يُسمح بعملية DML على كائن الإعداد بعد تحديث كائن غير محدد (أو عكس): المستخدم ، الكائن الأصلي: الحساب

لاحظ أن الخطأ لا يحدث عند تشغيل الاختبارات من Eclipse/Force.com IDE ، ولكنه يحدث عند نشره على Salesforce ثم قم بإجراء الاختبارات من داخل Salesforce.

كيف يمكنني إعادة كتابة اختباراتي لتجنب هذا الخطأ؟

إليك مثال بسيط على اختبار يسبب الخطأ:

static testMethod void test_mixed_dmlbug() {        
    Profile p = [select id from profile where name='(some profile)'];
    UserRole r = [Select id from userrole where name='(some role)'];
    User u = new User(alias = 'standt', email='standarduser@testorg.com', 
            emailencodingkey='UTF-8', lastname='Testing', 
            languagelocalekey='en_US', 
            localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
            timezonesidkey='America/Los_Angeles', 
            username='standarduser@testorg.com');
    Account a = new Account(Firstname='Terry', Lastname='Testperson');
    insert a;

    System.runAs(u) {
        a.PersonEmail = 'test@madeupaddress.com';
        update a;
    }

}
هل كانت مفيدة؟

المحلول

ليس هناك الكثير من الناس Salesforce هنا بعد ، على ما أعتقد.

لقد وجدت حلاً ، لا أعرف لماذا يعمل ، لكنه يعمل.

جميع أجزاء الاختبار التي تصل إلى الكائنات العادية تحتاج إلى لفها في نظام. runas يستخدم بشكل صريح المستخدم الحالي ، مثل هذا:

User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
System.runAs ( thisUser ) {
    // put test setup code in here
}

لذا ، فإن طريقة text_mixed_dmlbug الواردة في السؤال ، ستصبح:

static testMethod void test_mixed_dmlbug() {  
    User u;
    Account a;      
    User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
    System.runAs ( thisUser ) {
        Profile p = [select id from profile where name='(some profile)'];
        UserRole r = [Select id from userrole where name='(some role)'];
        u = new User(alias = 'standt', email='standarduser@testorg.com', 
            emailencodingkey='UTF-8', lastname='Testing', 
            languagelocalekey='en_US', 
            localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
            timezonesidkey='America/Los_Angeles', 
            username='standarduser@testorg.com');
        a = new Account(Firstname='Terry', Lastname='Testperson');
        insert a;
    }
    System.runAs(u) {
        a.PersonEmail = 'test@madeupaddress.com';
        update a;
    }

}

ثم تتوقف أخطاء mixed_dml_operation عن حدوثها.

نصائح أخرى

يبدو أنك وجدت حلًا بديلًا. أردت فقط أن أحاول توضيح سبب حصولك على هذا الخطأ.

أعتقد أنك تواجه هذه المشكلة (لكل http://www.salesforce.com/us/developer/docs/apexcode/content/apex_dml_non_mix_sobjects.htm):

البخاخات التي لا يمكن استخدامها معًا في عمليات DML

تتطلب بعض عمليات الرغبة في إجراء عمليات DML على نوع واحد فقط لكل معاملة. على سبيل المثال ، لا يمكنك إدراج حساب ، ثم أدخل مستخدمًا أو عضوًا في المجموعة في معاملة واحدة. لا يمكن استخدام الرائحة التالية معًا في معاملة:

* Group1
* GroupMember
* QueueSObject
* User2
* UserRole
* UserTerritory
* Territory

من المهم الاستثناء الأساسي لذلك هو عندما تستخدم طريقة Runas في الاختبار.

بالإضافة إلى ذلك ، ملاحظات إصدار الصيف 08 (هذا الرابط هو PDF) قل:

في الإصدارات السابقة ، في معاملة واحدة تتضمن مشغلات ، يمكنك تنفيذ عمليات DML على أكثر من نوع واحد من sobject ، على سبيل المثال ، يمكنك إدراج حساب ، ثم إدراج مستخدم. اعتبارًا من Summer '08 ، يمكنك فقط إجراء عمليات DML على نوع واحد من الرصاص من القائمة التالية من عمليات الرابطة.

على سبيل المثال ، لا يمكنك إدراج حساب ، ثم أدخل مستخدم ، أو تحديث مجموعة ، ثم أدخل عضوًا في المجموعة.

  • مجموعة
  • GroupMember
  • QueUESOBject
  • المستعمل
  • دور المستخدم
  • المستخدم
  • إِقلِيم

بالإضافة إلى ذلك ، يدعم المستخدمون والأراضي الآن إدراج عمليات DML وتحديثها ، ويدعم USERROLE الآن عمليات الإدراج وتحديث عمليات DML وتراجعها.

لا يتم دعم عمليات Apex DML على الرصاصات التالية:

  • المشهد
  • المشهد
  • userAccountTeamMember

تم توثيق هذا السلوك بالفعل في وثائق Salesforce: http://www.salesforce.com/us/developer/docs/apexcode/index_left.htm#starttopic=content/apex_dml_non_mix_sobjects.htm؟searchtype. اقرأ أين تقول "من المهم الاستثناء الأساسي لذلك هو عندما تستخدم طريقة Runas في اختبار"

وجدت هذا للتو في الوثائق:

استخدامات أخرى runAs

يمكنك أيضا استخدام runAs طريقة لإجراء عمليات DML مختلطة في الاختبار عن طريق إرفاق عمليات DML داخل runAs الكتلة. وبهذه الطريقة ، يمكنك تجاوز خطأ DML المختلط الذي يتم إرجاعه خلاف ذلك عند إدخال أو تحديث كائنات الإعداد مع الآخرين sObjects. نرى sObjects لا يمكن استخدامها معًا في عمليات DML.

لذلك يبدو مثل RunAs الحل البديل ليس بديلًا ولكن يفترضه Salesforce كطريقة الوحيدة للذهاب إلى مشكلة DML المختلطة.

أتمنى أن يساعدك هذا

المرجعي

هذا الخطأ شائع جدًا عند محاولة إنشاء سجلات المستخدم وغيرها من الكائنات في معاملة واحدة في Apex.

حل الحل في Apex Class/Trigger: استخدم الطريقة المستقبلية لإنشاء المستخدم عند مواجهة الخطأ

حل بديل في فئة الاختبار: لا تحاول إنشاء بيانات مستخدم جديدة ، بدلاً من ذلك استخدم))>

رمز snippet في -https://thesalesforcedev.blogspot.com/2019/07/mixeddmloperation-dml-operation-on.html

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top