Ошибка Salesforce Apex: SELF_REFERENCE_FROM_TRIGGER

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger triggerOpportunityCloseInstallDateChange caused an unexpected exception, contact your administrator: triggerOpportunityCloseInstallDateChange: execution of BeforeUpdate caused by: System.DmlException: Delete failed. First exception on row 0 with id 00o30000003ySNhAAM; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = 0063000000i23T9) is currently in trigger triggerOpportunityCloseInstallDateChange, therefore it cannot recursively update itself: []: Class.OpportunitySchedule.BuildScheduleAndUpdateDates: line 17, column 5

Я получаю указанную выше ошибку, когда пытаюсь выполнить приведенный ниже код.

У меня есть триггер «до» возможности. Затем он вызывает указанный ниже класс с помощью trigger.new.

public with sharing class OpportunitySchedule {

    public static void BuildScheduleAndUpdateDates(List<Opportunity> OpportunityList) {

        for (Integer i = 0; i < OpportunityList.size(); i++)
        {
            Opportunity opp_new = OpportunityList[i];

            List<OpportunityLineItem> lineItems = [Select o.Id, (Select OpportunityLineItemId From OpportunityLineItemSchedules), o.System_Add_on__c, o.ServiceDate, o.Schedule_Length__c , o.Monthly_Quantity__c, o.Monthly_Amount__c
                                                From OpportunityLineItem o
                                                where o.Opportunity.Id =  :opp_new.Id];

            for (OpportunityLineItem item : lineItems)
            {
                item.ServiceDate = opp_new.CloseDate;
                update item;
                delete item.OpportunityLineItemSchedules;       
            }                                   
        }
    }
}

Я пытаюсь удалить все расписания позиций возможностей, когда кто-то редактирует возможность. Странно то, что я могу удалить строку удаления item.OpportunityLineItemSchedules, и код запустится, он обновит элемент. Я не понимаю, почему удаление дочерних элементов (Opportunity -> OpportunityLineItem -> OpportunityLineItemSchedule) может вызвать рекурсивный цикл.

Я безуспешно пытался внедрить приведенный ниже код в эту ссылку: http://boards.developerforce.com/t5/Apex-Code-Development/Trigger-is-fired-twice-due-to-the-workflow.. .

Я также закомментировал все другие триггеры, чтобы убедиться, что один из них не вызывает это.

Кто-нибудь знает, что я делаю неправильно?


person Nate    schedule 08.09.2011    source источник


Ответы (2)


Несколько вещей, которые я заметил. Во-первых, никогда не помещайте DML внутрь цикла и особенно внутри триггера. Полезно прочитать о триггерах Bulkified здесь: http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_triggers.htm

В вашем коде вы почти там. Вместо того, чтобы выполнять обновление в цикле, просто обновите весь список после цикла:

for (OpportunityLineItem item : lineItems)
{
   item.ServiceDate = opp_new.CloseDate;
   //update item;
   //delete item.OpportunityLineItemSchedules;       
}

update lineItems;

Затем вы должны создать новый список только расписаний OpportunityLineItemSchedules, у которых ParentId == OpportunityLineItem.Id. Затем вы удалите весь этот список за один вызов:

delete saidList;

Что касается рекурсии, то в отношении мастер-подробности Force.com будет автоматически обрабатывать удаление дочерних элементов. Не так в поиске, где вам нужно удалить их вручную. Хотя я не уверен конкретно в OpportunityLineItemSchedules, я бы попробовал либо начать с использования триггера AFTER, либо использовать вспомогательный класс, который ваш поток триггера хранит в памяти, чтобы гарантировать, что, оказавшись внутри вашего класса обработчика триггера, он не введите его снова.

К сожалению, это все, чем я успел поделиться! Удачи и добро пожаловать в программирование Force.com. Надеюсь, он у вас вырастет.

person Adam    schedule 09.09.2011

Я не понимаю, почему удаление дочерних элементов (Opportunity -> OpportunityLineItem -> OpportunityLineItemSchedule) может вызвать рекурсивный цикл.

При использовании расписаний выручки TotalPrice родительского элемента OpportunityLineItem обновляется на основе связанных расписаний OpportunityLineItemSchedules. Таким образом, когда вы удаляете записи OpportunityLineItemSchedule, вы фактически обновляете OpportunityLineItem, что вызывает исключение DML SELF_REFERENCE_FROM_TRIGGER.

См. воздействие на возможности и позиции возможностей. раздел документации OpportunityLineItemSchedule.

Удаление OpportunityLineItemSchedule имеет аналогичный эффект для связанных OpportunityLineItem и Opportunity. При удалении OpportunityLineItemSchedule значение OpportunityLineItem TotalPrice уменьшается на удаленное значение OpportunityLineItemSchedule Quantity или Revenue. Сумма возможности также уменьшается на величину количества или дохода OpportunityLineItemSchedule Quantity или Revenue, а ожидаемая прибыль возможности уменьшается на сумму OpportunityLineItemSchedule Quantity или Revenue, умноженную на вероятность возможности.

person Daniel Ballinger    schedule 13.05.2012
comment
Привет всем, у меня такая же проблема. Пожалуйста, нажмите на эту ссылку salesforce.stackexchange.com/questions/43871/ См. журнал. У меня такая же проблема. - person Ramesh S; 11.07.2014