【问题标题】:Salesforce Apex error: SELF_REFERENCE_FROM_TRIGGERSalesforce Apex 错误:SELF_REFERENCE_FROM_TRIGGER
【发布时间】:2011-09-08 20:49:07
【问题描述】:
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...

我还注释掉了所有其他触发器,以确保其中一个不会导致它。

有谁知道我做错了什么?

【问题讨论】:

    标签: salesforce apex-code


    【解决方案1】:

    我注意到了一些事情。首先,永远不要将 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;
    

    然后您将创建一个仅包含 ParentId == OpportunityLineItem.Id 的 OpportunityLineItemSchedules 的新列表。然后你会在一次调用中删除整个列表:

    delete saidList;
    

    至于递归,在主从关系中,Force.com 将自动处理子项的删除。在查找中并非如此,您需要手动删除这些。虽然我不确定 OpportunityLineItemSchedules 具体是什么,但我会尝试使用 AFTER 触发器来开始,或者使用触发器线程保存在内存中的帮助器类,以确保一旦进入触发器处理程序类,它不会再次输入。

    不幸的是,以上是我有时间分享的全部内容!祝你好运,欢迎来到 Force.com 编程。希望它在你身上成长。

    【讨论】:

      【解决方案2】:

      我不明白为什么删除 childs 的孩子(Opportunity -> OpportunityLineItem -> OpportunityLineItemSchedule)会导致递归循环。

      使用收入计划时,父 OpportunityLineItem 上的 TotalPrice 会根据关联的 OpportunityLineItemSchedules 进行更新。因此,当您删除 OpportunityLineItemSchedule 记录时,您实际上是在更新 OpportunityLineItem,这会导致 SELF_REFERENCE_FROM_TRIGGER DML 异常。

      请参阅 OpportunityLineItemSchedule 文档的 Effects on Opportunities and Opportunity Line Items 部分。

      删除 OpportunityLineItemSchedule 对相关的 OpportunityLineItem 和 Opportunity 有类似的影响。删除 OpportunityLineItemSchedule 会使 OpportunityLineItem TotalPrice 减少已删除的 OpportunityLineItemSchedule 数量或收入金额。 Opportunity Amount 也按 OpportunityLineItemSchedule Quantity 或 Revenue 金额减少,Opportunity ExpectedRevenue 通过 OpportunityLineItemSchedule Quantity 或 Revenue 金额乘以 Opportunity Probability 减少。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多