2012-04-13 6 views
3

ich einen Trigger auf einem Kontaktobjekt haben und wenn ich versuche, einen Benutzerdatensatz in diesem Trigger zu aktualisieren ich die folgende Ausnahme erhalten:MIXED_DML_OPERATION Fehler in Salesforce Apex-Trigger bei der Aktualisierung von Benutzerobjekten

„MIXED_DML_OPERATION, DML Betrieb auf Setup Objekt ist nicht zulässig, nachdem Sie ein nicht-Setup-Objekt (oder umgekehrt) aktualisiert haben: User, ursprüngliches Objekt: Kontakt“

Trigger-Code:

trigger UpdateContactTrigger on Contact (after update) { 

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

    u.IsActive = false; 
    update u; 

} 

Wie kann ich diesen Fehler zu vermeiden, während Benutzer Aktualisierung Rekord Felder aus einem Kontakt trig ger?

Antwort

9

Salesforce stuft Objekte in sogenannte Setup und Nicht-Setup-Objekte. Benutzer ist ein Setup-Objekt, während Contact ein Nicht-Setup-Objekt ist. Salesforce beschränkt DML-Vorgänge, sodass beide Arten von Objekten nicht im selben Kontext bearbeitet werden können.

Es gibt eine Problemumgehung für dieses Problem, bei dem DML-Code für ein in Konflikt stehendes Objekt mit einer @future-Methode versehen wird, wie am Ende dieser document und der vorherigen Antwort beschrieben.

In meinem Fall funktioniert die Methode @future nicht, weil es einen Aktualisierungstrigger für den Benutzer gab, der eine andere @future-Methode aufgerufen hat und Salesforce den Aufruf einer @future-Methode von einer anderen @future-Methode nicht zulässt.

So kam ich mit einem anderen Problem zu umgehen, die für Benutzerobjekte für einige Fälle funktioniert.

Von API-Version 15.0 Salesforce ermöglicht tatsächlich Updates auf benutzerdefinierte Felder eines Benutzerobjekts im selben Zusammenhang mit nicht-Setup-Objekt-Updates. Wenn Sie also das Standardfeld des Benutzers aktualisieren müssen, können Sie ein benutzerdefiniertes Proxy-Feld mit einem Trigger vor dem Update für das Benutzerobjekt verwenden.

Wenn Sie Benutzer- IsActive Feld zu ändern, fügen Sie eine benutzerdefinierte IsActiveProxy Feld für den Benutzer und führen Sie Ihre Aktualisierung in einem Trigger darauf:

trigger UpdateContactTrigger on Contact (after update) { 

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

    u.IsActiveProxy__c = false; 
    update u; 

} 

Dann erstellen Sie eine ‚vor der Aktualisierung‘ Trigger auf einen Benutzer, Kopien des Proxy-Feldwert auf das Standardfeld:

trigger BeforeUpdateUserTrigger on User (before update) { 

    for(User user : trigger.new) { 

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

    } 

} 

das ist es! Es hat für mich funktioniert.

2

Sie sollten @future Methode definieren, die das Update tun und diese Methode von Trigger aufrufen.

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

    u.IsActive = false; 
    update u; 
} 

und es in Lockruf:

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

Ja, ich habe diesen Ansatz versucht, aber es für mich nicht funktioniert, weil es auf dem Benutzer ein Trigger ist, die eine ‚@future‘ Methode und rief ‚@future‘ Methode von einer anderen ‚@future‘ Methode ruft in nicht erlaubt Zwangsversteigerung. Ich habe eine alternative Problemumgehung gefunden, die das Problem löst, und ich werde es als eine Antwort später veröffentlichen. Danke für die Antwort! –

Verwandte Themen