Как избежать ошибки MIXED_DML_OPERATION в тестах Salesforce, которые создают Пользователей

Иногда в Salesforce тестирует Вас, должен создать Пользовательские объекты для выполнения части теста как speciifc тип пользователя.

Однако с Лета Salesforce 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;
    }

}
32
задан skaffman 10 May 2011 в 16:54
поделиться

2 ответа

Думаю, здесь еще не так много сотрудников Salesforce.

Я нашел решение, не знаю, почему оно работает, но оно работает.

Все части теста, которые обращаются к обычным объектам, должны быть заключены в System.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 перестают возникать.

40
ответ дан 27 November 2019 в 20:34
поделиться

Похоже, вы нашли обходной путь . Я просто хотел попытаться выяснить, почему вы получили эту ошибку.

Думаю, вы столкнулись с этой проблемой (согласно http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_dml_non_mix_sobjects.htm ):

sObjects, которые не могут Совместное использование в операциях DML

Некоторые объекты sObject требуют, чтобы вы выполняли операции DML только с одним типом для каждой транзакции. Например, вы не можете вставить учетную запись, а затем вставить пользователя или члена группы в одну транзакцию. Следующие объекты sObject не могут использоваться вместе в транзакции:

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

Важно. Основное исключение для - это когда вы используете метод runAs в тесте.

Кроме того, в примечаниях к выпуску Summer 08 (эта ссылка представляет собой PDF-файл) говорится:

В предыдущих выпусках в одной транзакции , которая включала триггеры, {{1} } вы можете выполнять операции DML с более чем одним типом sObject, например , вы можете вставить учетную запись, затем вставить пользователя. Начиная с лета '08, вы можете выполнять операции DML только с одним типом sObject из следующего списка sObject.

Например, вы не можете вставить учетную запись , затем добавить пользователя или обновить группу, а затем вставить члена группы .

  • Группа
  • GroupMember
  • QueueSObject
  • Пользователь
  • UserRole
  • UserTerritory
  • Territory

Кроме того, теперь User и Territory поддерживают вставку и обновление DML { {1}}, а UserRole теперь поддерживает операции вставки, обновления, удаления и обновления DML.

Операции Apex DML не поддерживаются для следующих sObjects:

  • AccountTerritoryAssignmentRule
  • AccountTerritoryAssignmentRuleItem
  • UserAccountTeamMember
13
ответ дан 27 November 2019 в 20:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: