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
Don PierceDon Pierce 

I do not understand why this error occurs : SObject row was retrieved via SOQL without querying the requested field

This is the error:
Apex trigger QuoteLineItemTrigger caused an unexpected exception, contact your administrator: QuoteLineItemTrigger: execution of AfterUpdate caused by: System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: QuoteLineItem.QuoteId: Trigger.QuoteLineItemTrigger: line 34, column 1

Here is my code:
trigger QuoteLineItemTrigger on QuoteLineItem (after insert, after update){  
    
    // prevent recursion
    if (!QuoteLineItemUtility.TriggerIsRunning){
        QuoteLineItemUtility.TriggerIsRunning = true;

        Set<Id> QuoteIds = new Set<Id>();
 
        List<QuoteLineItem> lineItemsForUpdate = new List<QuoteLineItem>();

        // gather IDs first of quotes
        for (QuoteLineItem ql : trigger.new) {
            
                 QuoteIds.add(ql.QuoteId);
        }

        if (!QuoteIds.isEmpty()) {
            // get all line items for all of the above quotes in bulk so that we don't hit governor limits
            Id prevQuoteId;
            Double lastLineNumber;
            // we can query all and these triggered records in an after trigger, nothing missing
            for (QuoteLineItem ql : [Select Id, Item_Numbering__c
                                       From QuoteLineItem 
                                      Where QuoteId in :QuoteIds
                                   Order By QuoteId, Item_Numbering__c NULLS LAST]) {

                // These are coming in already grouped by the same quote
                // and are sorted by the line number within that group
                
                if (prevQuoteId == null || prevQuoteId != ql.QuoteId) {

                    // start fresh because this is the first iteration OR we made it to 
                    // another group of line items
                    prevQuoteId = ql.QuoteId;
                    lastLineNumber = 0.0; //back to default                   
                }

                // Set the new line numbers as needed
                if(ql.Item_Numbering__c == null || ql.Item_Numbering__c == 0) {

                    ql.Item_Numbering__c = lastLineNumber + 1;
                    
                    // Need to create a "new" in memory line item to break reference to the 
                    // trigger reference, otherwise you will get an error like "cannot update in an After trigger"
                    lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.Item_Numbering__c));
                }
                
                lastLineNumber = ql.Item_Numbering__c;

            } // end for

        }

        if (!lineItemsForUpdate.isEmpty())
            update lineItemsForUpdate; // DML only the changed line items

        QuoteLineItemUtility.TriggerIsRunning = false;
    }
}
Best Answer chosen by Don Pierce
Charan Thumma 15Charan Thumma 15
Hello Don,

Please change the SOQL to include QuoteId  in it

for (QuoteLineItem ql : [Select Id, Item_Numbering__c,QuoteId
                                       From QuoteLineItem 
                                      Where QuoteId in :QuoteIds
                                   Order By QuoteId, Item_Numbering__c NULLS LAST]) 

All Answers

Charan Thumma 15Charan Thumma 15
Hello Don,

Please change the SOQL to include QuoteId  in it

for (QuoteLineItem ql : [Select Id, Item_Numbering__c,QuoteId
                                       From QuoteLineItem 
                                      Where QuoteId in :QuoteIds
                                   Order By QuoteId, Item_Numbering__c NULLS LAST]) 
This was selected as the best answer
Don PierceDon Pierce
Too obvious thanks