有时,在Salesforce测试中,您需要创建用户对象,以将一部分测试作为用户的特定类型运行。

但是,由于Salesforce Summer 08更新,尝试在同一测试中创建用户对象和普通对象(例如帐户)的尝试导致以下错误:

混合_dml_operation,在更新非设置对象(或VICE反之亦然)后,设置对象上的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;
    }

}

然后混合_dml_operation错误停止发生。

其他提示

似乎您找到了解决方法。我只是想尝试清除为什么您会遇到此错误的原因。

我认为您正在遇到这个问题(每个问题 http://www.salesforce.com/us/developer/docs/apexcode/content/content/apex_dml_non_mix_mix_sobjects.htm):

在DML操作中不能一起使用的sobjects

一些Sobject要求您每次交易仅对一种类型进行DML操作。例如,您不能插入帐户,然后在单个事务中插入用户或组成员。以下sobjects不能在交易中一起使用:

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

重要的主要例外是当您在测试中使用runas方法时。

除此之外 夏季08发行笔记 (该链接是PDF)说:

在以前的版本中,在涉及触发器的单个交易中,您可以对多种类型的Sobject执行DML操作,例如,您可以插入帐户,然后插入用户。截至08年夏季,您只能从以下Sobjects列表中对单一类型的Sobject进行DML操作。

例如,您不能插入帐户,然后插入用户或更新组,然后插入组成员。

  • 团体
  • 组成员
  • queuesObject
  • 用户
  • Userrole
  • UserTerritor
  • 领土

此外,用户和领域现在支持插入和更新DML操作,现在,Userrole支持插入,更新删除和UPSERT DML操作。

APEX DML操作在以下Sobjects上不支持:

  • counterterritoryAssignmentrule
  • counterterritoryAssignmentRuleItem
  • Useraccountteammember

该行为实际上是在Salesforce文档中记录的: http://www.salesforce.com/us/developer/docs/apexcode/index_left.htm#starttopic=content/apex_dml_non_mix_mix_sobjects.htm?searchtype. 。请阅读说“重要的主要例外,当您在测试中使用runas方法时,

刚刚在文档中找到了这一点:

其他用途 runAs

您也可以使用 runAs 通过将DML操作包含在测试中的混合DML操作的方法 runAs 堵塞。通过这种方式,您绕过混合的DML错误,否则在将设置对象与其他插入或更新设置对象时返回 sObjects. 。看 sObjects 在DML操作中不能一起使用。

所以看起来像 RunAs 解决方法不是解决方法,而是Salesforce将其视为混合DML问题的唯一方法。

希望这可以帮助

参考

当尝试创建用户和其他对象在Apex中创建用户和其他对象记录时,此错误是如此普遍。

Apex类/触发器中的解决方法:在遇到错误时使用未来方法来创建用户

测试类中的解决方法:不要尝试创建新的用户数据,而是使用))>

代码nippet在 -https://thesalesforcedev.blogspot.com/2019/07/mixeddmloperation-dml-operation-on.html

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top