32 votes

Comment éviter MIXED_DML_OPERATION erreur dans Salesforce tests de créer des Utilisateurs

Parfois, dans Salesforce tests vous avez besoin pour créer des objets Utilisateur pour exécuter une partie de l'essai, comme un speciifc type d'utilisateur.

Toutefois, puisque la force de vente de l'Été 08 mise à jour, les tentatives de créer à la fois des objets Utilisateur et les objets normaux (tels que des Comptes) dans le même fil de test de l'erreur suivante:

MIXED_DML_OPERATION, opération DML sur la configuration de l'objet n'est pas permis après avoir mis à jour une non-installation de l'objet (ou vice versa): l'Utilisateur, l'objet d'origine: Compte

Notez que l'erreur ne se produit pas lorsque vous exécutez les tests à partir d'Eclipse/Force.com IDE, mais il ne se passe lorsque vous déployez pour Salesforce, puis exécutez les tests à partir de l'intérieur de Salesforce.

Comment puis-je reprendre mes tests pour éviter cette erreur?

Voici un exemple simple d'un test qui provoque l'erreur:

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;
    }

}

41voto

codeulike Points 9017

Pas beaucoup de Salesforce gens ici encore, je suppose.

J'ai trouvé une solution, je ne sais pas pourquoi cela fonctionne, mais ça fonctionne.

Toutes les parties du test que l'accès normal objets ont besoin d'être enveloppé dans un Système.runAs qui utilise explicitement l'utilisateur actuel, comme ceci:

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

Ainsi, l'exemple text_mixed_dmlbug la méthode donnée dans la question deviendrait:

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;
    }

}

Puis le MIXED_DML_OPERATION des erreurs d'arrêt de passe.

13voto

Paddyslacker Points 1621

Il semble que vous avez trouvé une solution de contournement. Je voulais juste essayer et clair pourquoi vous où obtenir cette erreur.

Je pense que vous êtes en cours d'exécution dans cette question (par http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_dml_non_mix_sobjects.htm):

nessobjects Qui Ne peut pas Être Utilisé dans les Opérations DML

Certains nessobjects vous demander d'effectuer les opérations DML sur un seul type par transaction. Par exemple, vous ne pouvez pas insérer un compte, puis insérez un utilisateur ou un membre d'un groupe en une seule transaction. La suite nessobjects ne peut pas être utilisée dans une transaction:

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

Important La principale exception à c'est quand vous êtes à l'aide de la runAs méthode de test.

En outre, l' Eté 08 notes de Version (le lien est un fichier PDF) dire:

Dans les versions précédentes, en un seul opération qui a impliqué des déclencheurs, vous pourriez effectuer des opérations DML sur plus d'un type de sObject, pour exemple, vous pouvez insérer un compte, ensuite, insérez un utilisateur. À compter de l'Été '08, vous ne pouvez effectuer DML opérations sur un seul type de sObject à partir de la liste suivante des nessobjects.

Par exemple, vous ne pouvez pas insérer un compte, puis insérez un utilisateur, ou de mise à jour un groupe, puis insérez un groupe membre.

  • Groupe
  • GroupMember
  • QueueSObject
  • L'utilisateur
  • UserRole
  • UserTerritory
  • Territoire

En outre, l'Utilisateur et le Territoire maintenant soutenir l'insertion et mise à jour DML les opérations, et UserRole prend désormais en charge les commandes insert, update delete et upsert opérations DML.

Apex opérations DML ne sont pas pris en charge sur la suivante nessobjects:

  • AccountTerritoryAssignmentRule
  • AccountTerritoryAssignmentRuleItem
  • UserAccountTeamMember

7voto

Jorge Points 51

Ce comportement est documentée dans le salesforce documentation: http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_dml_non_mix_sobjects.htm?SearchType. Lire où il dire "Important La principale exception à cette règle est lorsque vous utilisez le runAs méthode dans un test"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X