function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Kenji775Kenji775 

Recursive Update Problem

Hello all,

I have a trigger that is throwing

 

"Error:Apex trigger CancelStudy caused an unexpected exception, contact your administrator: CancelStudy: execution of BeforeUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id a0CR0000001posKMAQ; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = 701R00000002Xyt) is currently in trigger CancelStudy, therefore it cannot recursively update itself: []: Trigger.CancelStudy: line 74, column 4"

 

I have disabled all other triggers on the respondent__c object (the type of record that is getting updated in the last statment that seems to be causing this issue). Respondent__C objects have a master detail relationship with campaigns, so maybe that is part of the problem? I don't really know. Any thoughts or insight is much appreciated. Thank you!

 

 

trigger CancelStudy on Campaign (before update) 
{
	//This trigger needs to find all respondents attached to any passed in campaign,
	//and send them an email, the email text is contained in a field on the campaign

	//Basic Heirarchy
	//Campaign <----(Master Detail)---- Respondent__C 
	
	//This trigger receives campaigns. From the campaigns we can find all attached respondents.
	//Respondents have contacts attached as well, so we can find the peoples email addresses.
	//A respondent__c is linked to a campaign by the Master_Campaign__c field on the respondent__c.
	
	
	
	//create a list to hold all campaign Id's we are going to need to find respondents for
	List<Id> campaignIds = new List<Id>();
	
	//Loop over all the campaigns passed in
	for(Campaign c:Trigger.new)
	{
		//If this campaign is set to be cancelled and the password is correct, add it to the list
		//Yes I know this is a stupid password, I'm gonna change it later.
		if(c.Cancel_Study__c == true && c.Cancel_Study_Password__c == 'stupidUglyFace')
		{
			//Add the Id to the list
			campaignIds.add(c.Id);
			
			//Update the status of this campaign
			c.Status = 'Canceled';
		}
		
		//If this campaign is set to be canelled but the password is not correct, error that record
		else if(c.Cancel_Study__c == true && c.Cancel_Study_Password__c != 'stupidUglyFace')
		{			
			c.Cancel_Study_Password__c.addError('Incorrect Password. Study not cancelled');	
		}
		
		//Blank out these fields so this trigger doesn't get rerun on subsequent saves
		c.Cancel_Study_Password__c = '';
		c.Cancel_Study__c = false;
		
	}
	
	//So now we have a map of campaigns to be cancelled
	//Now we need to figure out who we need to send emails to (those are sent via a workflow rule). 
	//That would be any respondent__c record with one of the campaigns specified in the map 
	//set as their master that are not cancelled already.
	
	System.debug('-----------------------------------------');
	System.debug('Canceling Studies' +campaignIds);

	if(campaignIds.size() > 0)
	{	
		//A list of all the respondent records to update with a canceled status
		List<Respondent__c> canceledRespondents = new List<Respondent__c>();
								
		
		//Find every respondent__c record that belongs to one of the campaigns being canceled.
		//Update their status and cancelation reason that will cause the workflow rule to fire
		for (Respondent__c respondent : [SELECT respondent__c FROM Respondent__c WHERE Master_Campaign__c IN :campaignIds and Respondent_Status__c = 'Scheduled'])
		{		
			//We want to mark the indivdual respondent record as canceled so the triggers, that will send the proper emails
			Respondent__c newRespondent = new Respondent__c(Id=String.valueOf(respondent.get('Id')));
			newRespondent.Respondent_Status__c = 'Canceled';
			newRespondent.Cancelation_Reason__c = 'Study Canceled';
			canceledRespondents.add(newRespondent);
		}
		

		System.debug('-----------------------------------------');
		System.debug('Updating Respondent Records' +canceledRespondents);
				
		//If there are any canceled Respondents, update their records so those triggers fire.
		if(canceledRespondents.size() > 0)
		{
			//This line is causing a recursive update problem.
			//I think maybe because the type of records it is attempting to update 
			//have a master detail relationship with the kind of record that fires this trigger?
			update canceledRespondents;
		}
	}	
}

 

 

User@SVFUser@SVF

Kenji,

 

Try declaring a class as:

public with sharing class StaticVariables 
{
    public static Boolean beforeUpdateCampaign = true;
}

 

 

Once the above code is defined, check the condition in your trigger as:

 

trigger CancelStudy on Campaign (before update) 
{
If(StaticVariables.beforeUpdateCampaign){
   StaticVariables.beforeUpdateCampaign = FALSE;  
   //your trigger code goes here.
}

 

 

Since your static variables class has only the static variables declared, it does not require any test method for deploying to production. Check if the above solution fits/resolves your requirement.

 

*** and enable all the triggers you have disabled.

 

Hope this helps

 

Prudhvi kamal.

Kenji775Kenji775

Ill give it a shot and let ya know. Thanks.

Kenji775Kenji775

Unfortunatly that did not resolve the problem. I think it still detects a loop because the trigger gets called again, even though the processing aborts immediatly afterward, the trigger still does get called a 2nd time. I really wish I knew why it was getting called again, I do not know what it causing that. Any other thoughts or ideas?