1

I have this VF page:

<apex:page standardController="Quote" standardstylesheets="false" sidebar="false" applyBodyTag="false" extensions="QuoteExt" renderAs="PDF">

<apex:repeat value="{!Quote.Quotelineitems}" var="qli" id="qli" rendered="false">
  <apex:outputtext value="{!qli.Product2.name}" />
  <apex:outputtext value="{!qli.Product2.Included_features__c}" />
  <apex:outputtext value="{!qli.Product2.Limits__c}" />
  <apex:outputtext value="{!qli.Product2.Type__c}" />
  <apex:outputtext value="{!qli.Quantity}" />
</apex:repeat>

[...]

And this controller:

public class QuoteExt {
    private final Quote quote;
    public QuoteExt(ApexPages.StandardController stdController) {
        this.quote = (Quote)stdController.getRecord();
    }

    public Map<String, Boolean> getCombinedPlanIncludedFeatures() {
        Map<String, Boolean> included_features = new Map<String, Boolean>();        

        for(QuoteLineItem l: quote.QuoteLineItems) {
          if (l.Product2.Type__c=='Subscription' || l.Product2.Type__c=='Add-on') {
--->        System.debug(l.Product2.Included_features__c); 
          }
        }
        return included_features;
    }
[...]

The marked line fails with: System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Product2.Included_features__c

I have no idea why. The field is a multi picklist type if that helps.

Thanks in advance!

Regards, Jacob

5
  • Isn't that what I'm already doing when I use the fields in the VF page?
    – jriff
    Commented Oct 4, 2016 at 18:33
  • You need to query QuoteLineItem with fields --- Product2.name,Product2.Included_features__c... and then use that list in visualforce page and I don't see it in your code
    – sfdc
    Commented Oct 4, 2016 at 18:34
  • 2
    @jriff - The controller brings in the quote fields from the markup on the VF page, I do not believe that it brings in the related object fields simply by including them in the markup. Best way to resolve it it to query for the Quotelineitems and use that in your code. Unless I am mistaken of course. For me though, when it looks like it should work and it does not, I move on to an alternate way (just query for them) rather than spend the time to figure out if what I think should happen is correct because it obviously is not given the error message
    – Eric
    Commented Oct 4, 2016 at 18:49
  • I completely agree with Eric about finding an alternate way to move things along but you should be able to access those fields with the standard controller. I threw your code into my dev org and had no problem accessing the related fields. Is it possible some of your changes aren't committed? You may want to try refreshing your resources.
    – gofestive
    Commented Oct 4, 2016 at 21:46
  • See answer below, looks like at least with v38 on my assumption is incorrect
    – Eric
    Commented Oct 5, 2016 at 7:07

1 Answer 1

1

(V38)

The standard controller method getRecord() has implicit access to all fields referenced in the VF markup, including child and parent relationships, and including fields referenced in apex:variable

The child relationships makes sense because otherwise how would a detail page work with related lists (or, for that matter, a VF email template that uses {!relatedTo.someChildRelName} markup to generate rows for a datatable or repeat.

Here's a sample VF page that uses the standard controller+extension

<apex:page standardController="Opportunity" extensions="OpportunityGetRecordScope">

    <apex:outputField value="{!Opportunity.Name}"/>
    <p></p>
    <apex:repeat value="{!Opportunity.OpportunityLineItems}" var="oli">

        <apex:outputField value="{!oli.quantity}"/>
        <apex:outputField value="{!oli.PricebookEntry.Product2.ProductCode}"/>
    </apex:repeat>

    <apex:variable value="{!Opportunity.Amount}" var="amt"/>
</apex:page>

and here's the controller

public class OpportunityGetRecordScope {

    public OpportunityGetRecordScope(ApexPages.StandardController ctlr) {
        Opportunity o = (Opportunity) ctlr.getRecord(); // the getRecord()

        System.debug(LoggingLevel.INFO, 'Opportunity Name:' + o.Name);
        for (OpportunityLineItem oli: o.OpportunityLineItems)
            System.debug(LoggingLevel.INFO,
                         'OLI field and lookup from OLI field via PBE.Product2:' + 
                             oli.Quantity + ' ' + oli.PricebookEntry.Product2.ProductCode);
        System.debug(LoggingLevel.INFO,' Oppo field in markup as an apex:variable:' + 
                                       o.Amount);

    }

}

No System.SObjectException: SObject row was retrieved via SOQL without querying the requested field occurred.

I even tried rendered="false" as in your example, and that made no difference

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .