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?
Best Answer
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:
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:
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.