开发者

Salesforce Apex error: SELF_REFERENCE_FROM_TRIGGER

开发者 https://www.devze.com 2023-04-04 03:12 出处:网络
Error: Invalid Data. Review all error messages below to correct your data. Apex trigger triggerOpportunityCloseInstallDateChange caused an unexpected exception, contact your administrator: triggerOpp
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

I'm getting the above error when I try to excute the code below.

I have a trigger on the "before" of an opportunity. It then calls the below class with 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;       
            }                                   
        }
    }
}

I'm trying to delete all of the Opportunity Line Item Schedules when someone edits an opportunity. The weird thing is, I can remove the delete item.OpportunityLineItemSchedules line and the code runs, it will update the item. I don't understand why deleting a childs children (Opportunity -> OpportunityLineItem -> OpportunityLineItemSchedule) would cause a recursive loop.

I've tried implimenting the below code in this link with no luck: http://boards.developerforce.com/t5/Apex-Code-Development/Trigger-is-fired-twice-due-to-the-workflow...

I've also commented out all other triggers to make sure one of them aren't causing it.

Does anyone know what I'm doing wrong?


A few things I noticed. First, never put DML inside a loop and especially when inside of a trigger. Reading up on Bulkified triggers here would help: http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_triggers.htm

In your code you're almost there. Instead of doing your update in the loop, simply update your entire list after the loop:

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

update lineItems;

Then you would make a new list of just OpportunityLineItemSchedules that had ParentId == OpportunityLineItem.Id. Then you would delete that entire list in one call:

delete saidList;

As for the recursion, in a master-detail relationship Force.com will handle the deletion of children automatically. Not so in a lookup, where you need to delete these by hand. Though I'm uncertain about OpportunityLineItemSchedules specifically, I'd try either starting things with using an AFTER trigger, or use a helper class that your trigger thread keeps in memory to ensure that once inside of your trigger handler class, that it doesn't enter it again.

Unfortunately the above is all I had a moment to share! Good luck and welcome to Force.com programming. Hope it grows on you.


I don't understand why deleting a childs children (Opportunity -> OpportunityLineItem -> OpportunityLineItemSchedule) would cause a recursive loop.

When using revenue schedules the TotalPrice on the parent OpportunityLineItem is updated based on the associated OpportunityLineItemSchedules. So when you delete the OpportunityLineItemSchedule records you are effectively updating the OpportunityLineItem, which causes the SELF_REFERENCE_FROM_TRIGGER DML Exception.

See the Effects on Opportunities and Opportunity Line Items section of the OpportunityLineItemSchedule documentation.

Deleting an OpportunityLineItemSchedule has a similar effect on the related OpportunityLineItem and Opportunity. Deleting an OpportunityLineItemSchedule decrements the OpportunityLineItem TotalPrice by the deleted OpportunityLineItemSchedule Quantity or Revenue amount. The Opportunity Amount is also decremented by the OpportunityLineItemSchedule Quantity or Revenue amount, and the Opportunity ExpectedRevenue is reduced by OpportunityLineItemSchedule Quantity or Revenue amount multiplied by the Opportunity Probability.

0

精彩评论

暂无评论...
验证码 换一张
取 消