Подтвердить что ты не робот

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

Иногда в тестах Salesforce вам необходимо создать объекты User для запуска части теста в качестве определенного типа пользователя.

Однако, поскольку обновление 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='[email protected]', 
            emailencodingkey='UTF-8', lastname='Testing', 
            languagelocalekey='en_US', 
            localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
            timezonesidkey='America/Los_Angeles', 
            username='[email protected]');
    Account a = new Account(Firstname='Terry', Lastname='Testperson');
    insert a;

    System.runAs(u) {
        a.PersonEmail = '[email protected]';
        update a;
    }

}
4b9b3361

Ответ 1

Не так много людей 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='[email protected]', 
            emailencodingkey='UTF-8', lastname='Testing', 
            languagelocalekey='en_US', 
            localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
            timezonesidkey='America/Los_Angeles', 
            username='[email protected]');
        a = new Account(Firstname='Terry', Lastname='Testperson');
        insert a;
    }
    System.runAs(u) {
        a.PersonEmail = '[email protected]';
        update a;
    }

}

Затем прекращаются ошибки MIXED_DML_OPERATION.

Ответ 2

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

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

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

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

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

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

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

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

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

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

Кроме того, Пользователь и Территория теперь поддержка вставки и обновления DML операций и UserRole теперь поддерживает вставку, удаление обновления и активировать операции DML.

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

  • AccountTerritoryAssignmentRule
  • AccountTerritoryAssignmentRuleItem
  • UserAccountTeamMember

Ответ 4

Просто нашел это в документации:

Другое использование runAs

Вы также можете использовать метод runAs для выполнения смешанных операций DML в своем тесте, заключив операции DML в блок runAs. Таким образом, вы обходите смешанную ошибку DML, которая в противном случае возвращается при вставке или обновлении объектов настройки вместе с другими sObjects. См. sObjects, который нельзя использовать вместе в операциях DML.

Таким образом, похоже, что обходной путь RunAs - это не обходной путь, а Salesforce считает его единственным способом решения смешанной проблемы DML.

Надеюсь, это поможет

Ссылка

Ответ 5

Эта ошибка очень распространена при попытке создать записи о пользователях и других объектах в одной транзакции в apex.

Обходной путь в апекс-классе/триггере: используйте будущий метод для создания пользователя при возникновении ошибки

Обходной путь в тестовом классе: не пытайтесь создавать новые пользовательские данные, вместо этого используйте))>

фрагмент кода на -https://thesalesforcedev.blogspot.com/2019/07/mixeddmloperation-dml-operation-on.html