更新用户对象时Salesforce Apex触发器中出现混合\u DML\u操作错误

更新用户对象时Salesforce Apex触发器中出现混合\u DML\u操作错误,salesforce,apex-code,dml,Salesforce,Apex Code,Dml,我在联系人对象上有一个触发器,当我尝试更新此触发器中的用户记录时,会出现以下异常: “混合\u DML\u操作,在更新非安装对象后,不允许对安装对象执行DML操作(反之亦然):用户,原始对象:联系人” 触发代码: trigger UpdateContactTrigger on Contact (after update) { User u = [SELECT Id, IsActive FROM User WHERE IsActive = true]; u.IsActive =

我在联系人对象上有一个触发器,当我尝试更新此触发器中的用户记录时,会出现以下异常:

“混合\u DML\u操作,在更新非安装对象后,不允许对安装对象执行DML操作(反之亦然):用户,原始对象:联系人”

触发代码:

trigger UpdateContactTrigger on Contact (after update) {

    User u = [SELECT Id, IsActive FROM User WHERE IsActive = true];

    u.IsActive = false;
    update u;

}

在从联系人触发器更新用户记录字段时,如何避免此错误?

您应该定义@future method来执行更新,并从触发器调用此方法

@future
updateUser(){
    User u = [SELECT Id, IsActive FROM User WHERE IsActive = true];

    u.IsActive = false;
    update u;
}
并在触发器中调用它:

trigger UpdateContactTrigger on Contact (after update) {
    updateUser();
}    

Salesforce将对象分为所谓的设置对象和非设置对象。用户是设置对象,而联系人是非设置对象。Salesforce限制DML操作,因此不能在同一上下文中操作这两种对象

对于这个问题,有一个解决方法,将冲突对象的DML代码放到@future方法中,如本文结尾和前面的答案所述

在我的例子中,使用@future方法不起作用,因为调用另一个@future方法的用户上有一个更新触发器,Salesforce不允许从另一个@future方法调用@future方法

因此,我提出了另一种解决方法,在某些情况下适用于用户对象

从API版本15.0开始,Salesforce实际上允许在与非设置对象更新相同的上下文中更新用户对象的自定义字段。因此,如果需要更新用户的标准字段,可以在用户对象上使用带有“更新前”触发器的自定义代理字段

如果需要更改用户的IsActive字段,请向用户添加自定义IsActiveProxy字段,并在其上的触发器中执行更新:

trigger UpdateContactTrigger on Contact (after update) {

    User u = [SELECT Id, IsActive FROM User WHERE IsActive = true];

    u.IsActiveProxy__c = false;
    update u;

}
然后在将代理字段值复制到标准字段的用户上创建“更新前”触发器:

trigger BeforeUpdateUserTrigger on User (before update) {

    for(User user : trigger.new) {

        if(user.IsActive != user.IsActiveProxy__c) {
            user.IsActive = user.IsActiveProxy__c;
        }

    }

}

就这样!它对我有效。

是的,我尝试过这种方法,但对我无效,因为在Salesforce中,用户上有一个触发器调用'@future'方法,并且不允许从另一个'@future'方法调用'@future'方法。我已经找到了一个解决问题的替代方法,稍后我会将其作为答案发布。谢谢回复!