0

I have a trigger that fires on before update off the Opportunity and creates revenues records. I have a trigger that fires after insert on the Revenue object, that updates the Opportunity, which causes a self reference error. I thought it was a recursion issue, but that isn't the problem. I need the trigger firing on the revenue to update the opportunity and I need the opportunity to insert the revenue records. Is there a way to solve the self reference error?

Here is the code:

 trigger OpportunityTrigger on Opportunity (before update) {

bunch of code doing stuff here...removed for brevity

if(newRevenues.size() > 0) {    
    insert newRevenues; //this is the key line in this trigger
}
}

code commented out in this trigger to avoid the error:

trigger UpdateOppAmount on Revenue__c (after insert, after delete, after update) 
{
    /*
    List<Revenue__c> lstR = new List<Revenue__c>();    
    List<Id> lstId = new List<Id>();
    Set<Id> stId = new Set<Id>();
    Set<Id> oppIds = new Set<Id>();

     if(Trigger.isInsert || Trigger.isUpdate)
     {
         for(Revenue__c r: Trigger.new)
         {
             if(r.Amount__c != null && r.Opportunity__c != null && !stId.contains(r.Opportunity__c))
             {
                 stId.add(r.Opportunity__c);
                 lstId.add(r.Opportunity__c);
             }
             oppIds.add(r.Opportunity__c);
         }
     }

     if(Trigger.isDelete)
     {
         for(Revenue__c r: Trigger.old)
         {
             if(r.Amount__c != null && r.Opportunity__c != null && !stId.contains(r.Opportunity__c))
             {
                 stId.add(r.Opportunity__c);
                 lstId.add(r.Opportunity__c);
             }
             oppIds.add(r.Opportunity__c);
         }
     }   
     List<Opportunity> lstO = [Select Id, (Select Amount__c from Revenues__r) from Opportunity where Id IN:lstId];
     List<Opportunity> lstUpd = new List<Opportunity>();
     for(Integer i=0;i<lstO.size();i++)
     {
         Opportunity o = new Opportunity(id=lstO[i].id);
         List<Revenue__c> lstOr = lstO[i].Revenues__r;
         Decimal dAm = 0;
         Boolean bl = false;

         ///Added to resolve ticket 




         for(Integer j=0;j<lstOr.size();j++)
         {
             dAm = dAm + lstOr[j].Amount__c;
             bl = true;
         }

         Boolean IsCalledFromVFpage = false;
         String strURL = string.valueOf(URL.getCurrentRequestUrl().toExternalForm());
         system.debug('##############' + strURL);

         if(strURL!=null && strURL.contains('apexremote')){
             IsCalledFromVFpage = true;
         }
         System.debug('###### IsCalledFromVFpage : ' + IsCalledFromVFpage);
         if(IsCalledFromVFpage==false) o.Amount = dAm;


         if(dAm == 0 && bl == false)
         {
             o.Profiled__c = false;
         }
         else
         {
             o.Profiled__c = true;
         }
         lstUpd.add(o);

     }
     if(!lstUpd.isEmpty())
     {          
        update lstUpd; // error is throw on this line
     }

    List<Opportunity> opps = [SELECT Id, Profile__c FROM Opportunity WHERE Id IN :oppIds];
    if(opps.size() >0) {
        Opportunity Opp = opps[0];
        Opp.Profile__c = 'custom';
        update Opp;
    }
    */
     }
  • 1
    You might get better help if you share your code. – Adrian Larson Jul 7 '17 at 15:09
  • @AdrianLarson I added the code. I've tried to remove extraneous code to keep it condensed. – Dman100 Jul 7 '17 at 15:28
  • I think using the after update trigger on the Opportunity instead of before update might solve your problem. – Mohit Arora Jul 7 '17 at 15:46
  • 1
    Can you please also include the error message verbatim? – Adrian Larson Jul 7 '17 at 15:48
  • 1
    I've rolled back your edit that removed the provided code because that information gives vital context to the answer you've accepted. Without that code, people who may come here with a similar problem and view this question in the future would be less likely to apply the answer to their own situations. – Derek F Jul 7 '17 at 15:59
2

In the Before Update of Opportunity, you are inserting Revenue. And in after insert of Revenue you are updating Opportunity again,

All that happens in same transaction. So your Debug log would look like


OpportunityTriggerStart Before

RevenuTriggerStart Before

RevenuTriggerEND Before

RevenuTriggerStart After

OpportunityTriggerStart Before again. The error reason.


So it means its recursively calls Opportunity Trigger. Thus the self referential error you get.

  1. There is a general rule that we insert/update the related related records in after triggers. You have to write opportunity trigger in after update event.
  2. Plus you should use Static variables in Trigger handler to recursive update of opportunity.

This will help you understand Recursive Trigger

What are recursive triggers? how to control them? Please provide an example also

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.