You need to sign in to do that
Don't have an account?

Two Triggers Cannot Recursively Update Itself
I am working on an application where the user will create a custom object (mps) record from the opportunity and a trigger will update certain fields on the mps from the opportunity.When there is an MPS record attached to the opportunity, the opportunity will update the mps, and when the mps is updated, the opportunity is updated. This has created an error that says "...cannot recursively update itself..." I am trying to find a way to prevent this. The problem is I cannot the find a way to break this recursion.
I wannt both records to be updated when one record is updated. Below are my triggers:
trigger OppUpdateMPS on Opportunity (before update) { Map<Id, Id> mapOpportunitytoMPS = new Map<Id, Id>(); for(Opportunity o : trigger.new){ // Populate map of Opportunity.Id to MPS.Id if (o.MPS__c != null) { mapOpportunitytoMPS.put(o.Id, o.mps__c); } } if (!mapOpportunitytoMPS.isEmpty()) { // Query all relevant opportunities to a map with key of Opportunity.Id Map<Id, MPS__c> mps = new Map<Id,MPS__c>([select id, MPS_BV__c, MPS_Comment__c, MPS_Scheduled_Ship_Date__c, MPS_Status__c, Close_Date__c, LastModifiedDate, Projected_Ship_Date__c, Projected_On_Site_Delivery_Date__c, Forecast_Category__c, Combined_Probability__c, Recursive_Update__c from MPS__c where id in:mapOpportunitytoMPS.values()]); List<MPS__c> mpsToUpdate = new List<MPS__c>(); Id mpsId; MPS__c m; for (Opportunity s : trigger.new) { if (mapOpportunitytoMPS.containsKey(s.Id)) { // Get the MPS__c ID from the map mpsId = mapOpportunitytoMPS.get(s.Id); // Get the opportunity based on the opportunity ID m = mps.get(mpsId); // Set fields on MPS based on Opportunity m.Forecast_Category__c = s.ForecastCategoryName; m.Combined_Probability__c = s.Combined_Probability__c; m.Close_Date__c = s.CloseDate; m.Projected_Ship_Date__c = s.Projected_Ship_Date__c; m.Projected_On_Site_Delivery_Date__c = s.Projected_On_Site_Delivery_Date__c ; m.MPS_Scheduled_Ship_Date__c = s.MPS_Scheduled_Ship_Date__c; MPSToUpdate.add(m); } } // Update all MPS__c in one call update MPSToUpdate; } }
trigger MPSUpdate on MPS__c (Before Insert, Before Update) { Map<Id, Id> mapMpsToOpportunity = new Map<Id, Id>(); for(MPS__c mps : trigger.new){ // Populate map of MPS.Id to Opportunity.Id if (mps.OpportunityID__c != null) { mapMpsToOpportunity.put(mps.Id, mps.OpportunityID__c); } } if (!mapMpsToOpportunity.isEmpty()) { // Query all relevant opportunities to a map with key of Opportunity.Id Map<Id, Opportunity> opps = new Map<Id, Opportunity>([select id, MPS_BV__c, MPS_Comment__c, MPS_Scheduled_Ship_Date__c, MPS_Status__c, CloseDate, Projected_Ship_Date__c, Projected_On_Site_Delivery_Date__c, ForecastCategoryName, Combined_Probability__c from Opportunity where id in:mapMpsToOpportunity.values()]); List<Opportunity> oppsToUpdate = new List<Opportunity>(); Id oppId; Opportunity o; for (MPS__c s : trigger.new) { if (mapMpsToOpportunity.containsKey(s.Id)) { // Get the opportunity ID from the map oppId = mapMpsToOpportunity.get(s.Id); // Get the opportunity based on the opportunity ID o = opps.get(oppId); // Set fields on MPS based on Opportunity s.Forecast_Category__c = o.ForecastCategoryName; s.Combined_Probability__c = o.Combined_Probability__c; s.Close_Date__c = o.CloseDate; s.Projected_Ship_Date__c = o.Projected_Ship_Date__c; s.Projected_On_Site_Delivery_Date__c = o.Projected_On_Site_Delivery_Date__c; // Set fields on Opportunity based on MPS o.MPS_Status__c = s.MPS_Status__c; o.MPS_BV__c = s.MPS_BV__c; o.MPS_Comment__c = s.MPS_Comment__c; o.MPS_Scheduled_Ship_Date__c = s.MPS_Scheduled_Ship_Date__c; o.MPS__c = s.id; oppsToUpdate.add(o); } } // Update all opportunities in one call update oppsToUpdate; } }
I have thought about creating checkboxes to be checked when the a trigger updates a record, and reset the field with a time-based workflow, but I only need to stagger the time a few seconds before the field is reset. Is there any way I can achieve the same thing within the triggers?
Thanks,
ckellie
Hi ckellie,
I'm glad to see the trigger code is working for you. :) To avoid recursive trigger calls use the technique described in this developerforce recipe.
Mark
All Answers
Hi ckellie,
I'm glad to see the trigger code is working for you. :) To avoid recursive trigger calls use the technique described in this developerforce recipe.
Mark
Hi ckellie,
I suggest this would be easy with workflow's, instead of triggers.
The answer to your question is similar to below post:
http://boards.developerforce.com/t5/Apex-Code-Development/Trigger-is-fired-twice-due-to-the-workflow-rule-field-update/m-p/123469
Hope it helps,
Mark,
Thank you so much for your help. The page you sent me one recursive triggers did the trick and the the solved the challenge. Thank you very much.
ckellie
Rahul,
Thank you for the reference to the other workflow question. Unfortunately, workflows will not work as I am needing to update both records when one record is saved. Workflow rules only update the record you are working on after the record is saved, which will not meet our need.
Thank you for the suggestion,
ckellie
hI ckellie,
I to have same problem.
ian application where the user will create a custom object (mps) record from the opportunity and a trigger will update certain fields on the mps from the opportunity.When there is an MPS record attached to the opportunity, the opportunity will update the mps, and when the mps is updated, the opportunity is updated. This has created an error that says "...cannot recursively update itself..." I am trying to find a way to prevent this. The problem is I cannot the find a way to break this recursion
please help me.I dont know where exactly i need to keep static variables
can any one put static varibles in follwing code and send me back .
Thanking u
Raju,
Since working on this code, I found a solution that worked better for me.
1. Make a Master-Detail relationship Opportunity-MPS format.
2. All of the Opportunity-related fields can now be formula fields.
3. Add a lookup field the on the Opportunity.
4. Create a VF page/extension for the record creation.
5. Create an After Insert trigger updating the MPS__c lookup field on the Opportunity.
6. Create Opportunity formula fields to pull the MPS__c information onto the Opportunity.