2012-04-13 1 views
3

У меня есть триггер на объекте контакта и когда я пытаюсь обновить запись пользователя в этом триггере я получаю следующее исключение:MIXED_DML_OPERATION ошибки в Salesforce Apex Trigger, когда объекты обновления пользователя

«MIXED_DML_OPERATION, DML операции по установке объект не разрешается после того, как вы обновили объект без установки (или наоборот): Пользователь, исходный объект: Контакт»

код триггера:

trigger UpdateContactTrigger on Contact (after update) { 

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

    u.IsActive = false; 
    update u; 

} 

Как я могу избежать этой ошибки при обновлении пользователя пластинки полей из контактного триггера гер?

ответ

9

Salesforce классифицирует объекты в так называемые установки и не установки объектов. Пользователь - объект установки, а Contact - объект без установки. Salesforce ограничивает операции DML, так что оба типа объектов нельзя манипулировать в одном контексте.

Обходной путь для этой проблемы заключается в размещении кода DML для конфликтующего объекта на метод @future, как описано в конце этого document и в предыдущем ответе.

В моем случае использование метода @future не сработало, поскольку на пользователе появился триггер обновления, который вызвал другой метод @future, а Salesforce не позволяет вызывать метод @future из другого метода @future.

Так что я придумал другое обходное решение, которое работает для некоторых случаев для объектов User.

Из версии API 15.0 Salesforce фактически позволяет обновлять пользовательские поля объекта User в том же контексте с обновлениями без установки объектов. Поэтому, если вам нужно обновить стандартное поле пользователя, вы можете использовать настраиваемое поле прокси с триггером «до обновления» на объекте «Пользователь».

Если вам необходимо изменить 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; 
     } 

    } 

} 

Это все! Это сработало для меня.

2

Вы должны определить метод @future, который будет выполнять обновление и вызывать этот метод из триггера.

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

    u.IsActive = false; 
    update u; 
} 

и вызвать его в триггере:

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

Да, я пробовал этот подход, но он не работает для меня, потому что есть триггер для пользователя, который вызывает метод @future, и вызов метода «@future» из другого метода «@future» не допускается в Salesforce. Я нашел альтернативное решение, которое решает проблему, и я отправлю его как ответ позже. Спасибо за ответ! –