+ Start a Discussion
FinneyFinney 

Trigger cannot recursively update itself

Hi

 

I have 2 objects here

 

1) Account - Parent 

2) Showing - Child

 

When the status on the account is dead, I wanted the status on the Showing record also to be dead.

 

I have created a trigger to do it but I am getting a strange error.

 

Error:Apex trigger UpdateShowingStatus caused an unexpected exception, contact your administrator: UpdateShowingStatus: execution of BeforeUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id a0KJ0000001CKO5MAO; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, ShowingCount: execution of BeforeUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id 001J000000R4YjHIAV; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = 001J000000R4YjH) is currently in trigger UpdateShowingStatus, therefore it cannot recursively update itself: [] Trigger.ShowingCount: line 21, column 1: []: Trigger.UpdateShowingStatus: line 17, column 1

 

I am posting the 2 triggers here

 

 

trigger UpdateShowingStatus on Account (before update) {
List<ID> accIds = New List<ID>();

  for(Account a:Trigger.new)
{
    if(a.pb__Status__c == 'Dead'){
      accIds.add(a.Id);
    }
  }

  List<pb__Showing__c> s = [ SELECT id,Account__c,Status__c from pb__Showing__c where Account__c = :accIds];
  for(integer i = 0 ; i < s.size(); i++){
    s[i].Status__c =  'Dead';
    
  }

  update s;
}

 

This is another trigger which is causing the conflict

 

trigger ShowingCount on pb__Showing__c (before insert,before update) {
    
    // if(trigger.new[0].Account__c!=null)
    // {
    Account ac=[select id, No_of_Viewings__c from Account where id=:trigger.new[0].Account__c];
    
    //if(ac!=null)
    //{
    if(ac.No_of_Viewings__c == null)
    ac.No_of_Viewings__c =0;
        
        if(trigger.isinsert) {
            ac.No_of_Viewings__c +=1;
        }
    
        if(trigger.isupdate ) {
            if(trigger.new[0].Status__c == 'Cancelled')
            ac.No_of_Viewings__c -= 1; 
        }
    
    update ac;
  
}

 

Can someone help me to fix this error please.

 

Thanks and Kind Regards

 

Finney

Jeff MayJeff May

Your second trigger (on the pb_Showing__c custom object) is manipulating Account records, which is causing Account updates,which triggers an update to the pb_Showing__c member of the Account.  Can you get around this by using Workflows and Field Updates instead?  This let's you only fire under the conditions you care about.

crop1645crop1645

An all APEX solution to this - http://developer.force.com/cookbook/recipe/controlling-recursive-triggers is commonly used to avoid recursive triggers. 

 

The topic is also discussed at length in this wonderful book - http://danappleman.com/2012/08/05/advancedapex/ with some design patterns to use

Mayank_JoshiMayank_Joshi

Hey Finney ,

 

Is there any necessity in using Before Event in all your triggers ?Also if you were using Before event then you should not use Update ( ); Call explicitly . I have commented out those update calls into your Trigger.

 

Also try to make your trigger with Combination of After and Before event (if only , your requirement allows you ).

 

please check below code for commented update Statement(it will work in same manner) and Use of Sets instead of List :

 

 

trigger UpdateShowingStatus on Account (After update) {
//List<ID> accIds = New List<ID>();

Set<Id> accIds =New Set<Id> ();

for(Account a:Trigger.new)
{
if(a.pb__Status__c == 'Dead'){
accIds.add(a.Id);
}
}

List<pb__Showing__c> s = [ SELECT id,Account__c,Status__c from pb__Showing__c where Account__c = :accIds];
for(integer i = 0 ; i < s.size(); i++){
s[i].Status__c = 'Dead';

}

update s;
}

This is another trigger which is causing the conflict

trigger ShowingCount on pb__Showing__c (before insert,before update) {


Account ac=[select id, No_of_Viewings__c from Account where id=:trigger.new[0].Account__c];

if(ac.No_of_Viewings__c == null)
ac.No_of_Viewings__c =0;

if(trigger.isinsert) {
ac.No_of_Viewings__c +=1;
}

if(trigger.isupdate ) {
if(trigger.new[0].Status__c == 'Cancelled')
ac.No_of_Viewings__c -= 1;
}

// update ac;

}
}
}

 

Warm Regards, 

Ramesh SomalagariRamesh Somalagari
Hi All I have same problem.Can you please click this link http://salesforce.stackexchange.com/questions/43871/system-dmlexception-delete-failed-self-reference-from-trigger See the log I a have got same issue.

Vinod RajputVinod Rajput
HI All,
From UpdateShowingStatus  trigger you are updating pb__Showing__c object and From pb__Showing__c object you are updating Account that is not allowed , Reason
You have initiated before update(transection) event trigger from UpdateShowingStatus  which is updating pb__Showing__c object data and pb__Showing__c object trigger is updating account in context of before update so it is not allowed in salesforce , Inorder to achieve this functionality use after update event with help static helper class so you can avoid error.