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
abcd1234abcd1234 

Trigger throwing error: SELF_REFERENCE_FROM_TRIGGER

    Hi,

 

I have written a trigger for before update function

 

 

The trigger which iam running is

 

 

trigger stage_won on Opportunity (before update) {

 

     

   for (opportunity a : Trigger.new)        

   {             

    if ((a.StageName=='Closed Won')&&(a.Status__C!='Approved')&&(a.Requesting_Stage__c==null))

    {

      opportunity convertedopp = [select StageName,Requesting_Stage__c from opportunity where id = :a.id];

      convertedopp.Requesting_Stage__c = 'Closed Won';

      Update convertedopp;

      a.addError('Approval Required');

                  

     }

     }

     }

 

 

Its throwing the below error.

 

 

 

 

 

Apex script unhandled trigger exception by user/organization: 005N0000000Hdze/00DN00000000NEt Source organization: 00D90000000KgmL (null)

stage_won: execution of BeforeUpdate

caused by: System.DmlException: Update failed. First exception on row 0 with id 006N0000001qx7SIAQ; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = 006N0000001qx7S) is currently in trigger stage_won, therefore it cannot recursively update itself: []

Trigger.stage_won: line 10, column 7

 

sebcossebcos

Hi,

there a few of problems with the trigger.

Firstly, updating an opportunity that caused the before trigger to fire in in the trigger itself is not allowed and will throw a runtime exception as explained here:

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers.htm 

" Additionally, if you update or delete a record in its before trigger, or delete a record in its after trigger, you will receive a runtime error." 

 

Another problem is that you are trying to execute a SOQL query in  a for loop. This is not recommended in terms of performance and will incur in governor limits, refer to this:

http://wiki.developerforce.com/index.php/Best_Practice:_Avoid_SOQL_Queries_Inside_FOR_Loops

 

It looks like the trigger is supposed to validate that the status is approved and requesting stage is not null.

You only need to iterate over the trigger.new list and adderror if the conditions are met. You don't need to  query the opportunities again.

 

Finally, have you considered using a validation rule instead?

It should fulfill your requirement without writing code.

Something like this: 

 

StageName=='Closed Won' && Status__C<>'Approved' && Requesting_Stage__c==null

 

with an error message saying:

 

'Approval Required' .

abcd1234abcd1234

After supervsior approval only stage should be changed to closed won.

 

If i use validation it will be problem for me to create entry criteria for the approval process.Stage can move to closed won from any stage.So i am taking one more custom field as "requesting stage" .I am using that field as my entry criteria in approval process.

 

So i think i should write trigger to update the custom field.Please help me in resolving the issue.

 

 

Damien_Damien_

trigger stage_won on Opportunity (before update)

{

   for (opportunity a : Trigger.new)        

   {             

    if ((a.StageName=='Closed Won')&&(a.Status__C!='Approved')&&(a.Requesting_Stage__c==null))

    {

      a.Requesting_Stage__c = 'Closed Won';

      a.addError('Approval Required');

    }

   }

}

 

I think this is what you will need.  That query just brings back the record you are already working with.  All you want to do is update that one field.  This happens before the update happens in the database, so the change you make to the field will be captured in the database.

Pradeep_NavatarPradeep_Navatar

You need not to write the "Update convertedopp;" line because trigger itself update the record on for them it is executing if we use "before update" But if we use "after update" then need to query and update the same records.

abcd1234abcd1234

Thankyou for your suggestion.

 

While i am doing this we are using a.adderror()

 

so i think record in not saving so im not getting value into requesting stage.Both actions are not doing at a time.

 

Is there any other way to show a message in standard opportunity page without using adderror.

 

 

sebcossebcos

Hi, from a trigger there is no other way of rendering messages to the UI as per other than the adderror method :

http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_intro_apex_limitation.htm?SearchType=Stem .

 

There are two options for displaying messages on an opportunity page:

 

1) Create a visualforce page to render messages on the UI by using the ApexPages.addmessage method:

http://www.salesforce.com/us/developer/docs/pages/index_Left.htm#StartTopic=Content/apex_methods_system_apexpages.htm

http://www.salesforce.com/us/developer/docs/pages/index_Left.htm#StartTopic=Content/pages_controller_validation.htm?SearchType=Stem

 

2) Use standard validation error messages which do not require Visualforce development but a formula like the one I showed above.