+ Start a Discussion
go_bear_2001go_bear_2001 

Update Quote and Quoteline getting SELF_REFERENCE_FROM_TRIGGER

 Hi,
 
I'm having this SELF_REFERENCE_FROM_TRIGGER exception and don't know what causes this.  Basically, I need to write a trigger on Quote object so that if a Quote get approved, all Quote lines in that Quote would then have their Unit_Price set to Requested_Price.  A SFDC_520_Quote__c  is a master object,and SFDC_520_QuoteLine__c is detail object in a master-detail relationship.  The below exception was thrown on the line where I update Quote lines records.  In this case, I try to update Quote lines objects which are different from Quote objects, so I don't think I try to update the same objects on which the trigger get executed.  Can anybody give a light on this if you come across something similar?

UpdateQuotelineitems: execution of BeforeUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id a0I80000004PrzSEAS; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = a0J80000001R4cQ) is currently in trigger UpdateQuotelineitems, therefore it cannot recursively update itself: [] Trigger.UpdateQuotelineitems

 
======== 
trigger UpdateQuotelineitems on SFDC_520_Quote__c (before update) {
// Set of quote ids for which quote_line_items are changed
    Set<ID> idSet = new Set<ID>();
    List<SFDC_520_Quote__c> quote_list = new List<SFDC_520_Quote__c>();
    
    for (ID quoteId : Trigger.newMap.keySet()){
        if (Trigger.newMap.get(quoteId).Approved__c == true){
            idSet.add(quoteId);
            quote_list.add(Trigger.newMap.get(quoteId));
        }
    }            
    if (idSet.size() == 0)
        return;
List<SFDC_520_QuoteLine__c> quotelinesList = [select id, Quote__c, Customer_Requested_Price__c, Unit_Price__c from SFDC_520_QuoteLine__c where Quote__c in :idSet];
    if (quotelinesList.size() == 0)
        return;
        
for (SFDC_520_QuoteLine__c ql : quotelinesList) {
ql. Unit_Price__c = ql.Requested_Price__c;
}        
//update Quote line records
update quotelinesList;   
for (SFDC_520_Quote__c q1 : quote_list) {
q1.Quotelinetrigger_flag__c = true;
}
}
========== 
Cool_DevloperCool_Devloper

Is there any other trigger like on "QuoteLine" object?

Or is there any workflow which might be getting executed in the whole flow somewhere?

The exception means that the same record is getting updated again within the same conetxt!

Cool_D

go_bear_2001go_bear_2001

Cool_D, 

Thanks for your responses.  I checked all triggers we have and none is also operating on Quote or Quote_line objects.  I also de-activate all workflow and approval processes on Quotes but the exception is still there.  Here is my debug log, look very much like the trigger is the only thing gets executed: 

 

//Debug log  

========================= 

*** Beginning UpdateQuotelineitems on SFDC_520_Quote trigger event BeforeUpdate for a0JQ0000000Qy51 

20091124193158.409:Trigger.UpdateQuotelineitems: line 6, column 5: SelectLoop:SET:Id

20091124193158.409:Trigger.UpdateQuotelineitems: line 6, column 5:     Number of iterations: 1

20091124193158.409:Trigger.UpdateQuotelineitems: line 15, column 47: SOQL query with 1 row finished in 9 ms

20091124193158.409:Trigger.UpdateQuotelineitems: line 20, column 2: SelectLoop:LIST:SOBJECT:SFDC_520_QuoteLine__c

20091124193158.409:Trigger.UpdateQuotelineitems: line 20, column 2:     Number of iterations: 1

20091124193158.409:Trigger.UpdateQuotelineitems: line 25, column 2: Update: LIST:SOBJECT:SFDC_520_QuoteLine__c

20091124193158.409:Trigger.UpdateQuotelineitems: line 25, column 2:     DML Operation executed in 31 ms

System.DmlException: Update failed. First exception on row 0 with id a0IQ0000000HCQfMAO; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = a0JQ0000000Qy51) is currently in trigger UpdateQuotelineitems, therefore it cannot recursively update itself: []

Trigger.UpdateQuotelineitems: line 25, column 2 

Cumulative resource usage:

 

Resource usage for namespace: (default)

Number of SOQL queries: 1 out of 20

Number of query rows: 1 out of 1000

Number of SOSL queries: 0 out of 0

Number of DML statements: 1 out of 20

Number of DML rows: 1 out of 100

Number of script statements: 9 out of 10200

Maximum heap size: 0 out of 200000

Number of callouts: 0 out of 10

Number of Email Invocations: 0 out of 10

Number of fields describes: 0 out of 10

Number of record type describes: 0 out of 10

Number of child relationships describes: 0 out of 10

Number of picklist describes: 0 out of 10

Number of future calls: 0 out of 10

Number of find similar calls: 0 out of 0

Number of System.runAs() invocations: 0 out of 20

Total email recipients queued to be sent : 0

Static variables and sizes:

UpdateQuotelineitems:idSet:26

UpdateQuotelineitems:quote_list:8

UpdateQuotelineitems:quotelinesList:116

Stack frame variables and sizes:

  Frame0

    ql:0

    quoteId:0

*** Ending UpdateQuotelineitems on SFDC_520_Quote trigger event BeforeUpdate for a0JQ0000000Qy51

===================== 

Can't seem to figure out why.  I tried to do update on Quote_line objects and the trigger is on Quote objects.  Not sure as if a master-detail relationship plays any role into this, but I doubt this.  

Any suggestion is highly appreciated! 

go_bear_2001

 

Message Edited by go_bear_2001 on 11-24-2009 11:43 AM
go_bear_2001go_bear_2001

I think I figured out the issue.  Basically there is a roll-up summary field in the parent object (Quote) which calculates based on the Unit_price field of the child object (Quote_lines).  As such, in my trigger if I update this field on the child object (Quote_lines), the parent object needs to be updated as well for that roll-up field.  This leads to SELF_REFERENCE_FROM_TRIGGER exception.

 

Message Edited by go_bear_2001 on 11-24-2009 03:19 PM
Cool_DevloperCool_Devloper

Ahh ... i should have thought about roll-up summary:D 

So, you can put a check in your trigger to avoid the execution if it is a self-reference!

Cool_D

go_bear_2001go_bear_2001

Cool_D,

Would you mind to elaborate a little more on how do I put a check to avoid execution if it's self-reference?  I'm not sure how to provide a solution for this if I want to re-assign the value (Unit_Price__c) on Quote_lines objects, and at the same time maintaining the roll-up summary field on the parent Quote object somehow.

 

thanks for your inputs,

 

Cool_DevloperCool_Devloper

I think, you can check if the old value of the roll-up field has changed or not.

So, basically, you can put a check in your trigger-

if(Trigger.oldMap.get(id).fieldName__c <> Trigger.new.fieldname__c)

{

    //code here

}

What this will do is that, it will execute the trigger logic, only if the roll-up summary field value has changed. And that will ideally happen only once and hence trigger execution will also happen once;)

Cool_D