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
mmixmmix 

"SObject row was retrieved via SOQL without querying the requested field" for Owner field

I have an extension on a standard controller for my object GP_Bill_Item__c. Creating new entry works ok, but when I use this VF page for editing I get the above error when accessing Owner field from extension code. I know there is an optimization in field loading for edit as expressed in other topics, but no matter what I put in hidden output on VF page the owner does not seem to get loaded:

 

<apex:outputText value="{!billItem.Owner}" rendered="false"/> 

 

I tried different variations for this field but nothing seems to get the owner loaded. What am I doing wrong?

 

The code that fires an error:

 

public extension_GPBillItem(ApexPages.StandardController stdController)

{ this.billItem = (GB_Bill_Item__c)stdController.getRecord();

   // initial setup

   if (billItem.Owner == null) { billItem.OwnerId = UserInfo.getUserId(); } 

Best Answer chosen by Admin (Salesforce Developers) 
dchasmandchasman

GP_BIll_Item__c is a an instance member of the standard controller - we chose to use the name of the class as the name of the property that gets you to the root object because it is consistent with other areas in salesforce that set the precedent for this convention. There is most definitely a getGP_BIll_Item__c() accessor method on the SC class under the covers just like one that you would write in a custom controller. Alternate designs included using a this keyword approach but were not chosen for this reason.

 

As for the use of various design patterns we chose Mix In instead of IsA for a number of reasons - the main one being that implementation inheritance accross modules has also been a long understood anti pattern - suffers from fragile base class issues etc. IsA is typically not the correct relationship here - often extensions are used to aggregate in related but orthogonal functionality that is required by the presentation layer. The standard controller and its interaction with apex code has been made more and more sophisticated every release - e.g. you can now instantiate the SC and use it as a delegate in your code - something that was only recently made possible. Layer on top of all this the requirement that VF is supported in all sfdc editions - not all of which even have apex code authoring enabled/supported - and that the majority of "developers" using VF are not developers by trade and things get even more interesting... 

 

With all that said there is nothing stopping us from making something along the lines of an abstract StandardControllerBase system class in apex and allowing an apex code centric approach.To be honest you are the first personthat I am aware of to suggest this outside of salesforce R&D. I would strongly suggest that you create an idea on IdeaExchange and see if you can drum up some support...

 

Design patterns (and unfortunately anti patterns too) have been around since the begining of software and are in no way add odd with OOD/OOP concepts...

Message Edited by dchasman on 02-02-2009 08:39 AM
Message Edited by dchasman on 02-02-2009 08:46 AM

All Answers

mmixmmix

Ok, I got it to work, but I am now completelyp puzzled on how apex "figures out" which field to load???

 

It worked once I placed this after <form> tag:

 

 

<apex:outputText value="{!GB_Bill_Item__c.Owner.Name}" rendered="false"/>

 

Now, the thing is NONE of the fields I use in VF page were loaded... HOw does thi sactually work?

 

I have this definition in extension:

 

private final GB_Bill_Item__c billItem; 

public GB_Bill_Item__c getBillItem() {

return billItem;

 
 
and the field is on the VF page as:
 
<apex:inputField value="{!billItem.Hours__c}" required="true"/>
 
and yet I get the error:
 
System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: GB_Bill_Item__c.Hours__c
 
Why isnt the controller loading this field? Now, if I place this entry:
 
<apex:outputText value="{!GB_Bill_Item__c.Hours__c}" rendered="false"/>
 
I no longer get the error and it works... But this is bizare if I have to manually specify each and every field I need to use, where exactly is this automatic field list mechanism as it seems to load nothing but the ID.  

 

jeffdonthemicjeffdonthemic

You are fetching the record from the standard controller using the getRecord() method and the standard controller constructs the SOQL statement for you based upon the fields referenced in your Visualforce page. For performance considerations, it doesn't make sense to query all of the fields in your object when you are only referencing a small subset of them.

 

You are correctly adding a reference to them as a non-rendered field in your Visualforce page.

 

Jeff Douglas

Informa Plc

http://blog.jeffdouglas.com

mmixmmix
Yes, I get that story from other threads and I am not opposed to it, but it dos not seem to work well. The problem is that I am indeed referencing a field in a rendered element in VF page and the controller is not picking that up forcing me to add a non-rendered reference to the same field just so it would be loaded. Why is the the field building algorithm not picking up the Hours__c field?
dchasmandchasman

Automatic SOQL generation is a feature of the Standard Controller and the mechanism is based on scanning the page/component formulas contained in your markup. Any references inside of custom apex code is not going to be detected - this type of analysis is actually not even possible in many cases because of the layers of abstraction that apex code provides (e.g. class inheritance - both concrete and interface only, dynamic apex, etc).

 

You either need to do what you have already figured out (placing a non-rendered apex:outputText in your VF markup) or you can also perform your own custom SOQL inside your extension to retrieve the things that the Standard Controller cannot see.

dchasmandchasman
Can you please post a complete example that illustrates your situation? I suspect the disconnect here is something that we're not able to see from the fragments of code you have posted...
mmixmmix

Again, that is not the problem. I understand what you say and I understand that it is imposible to pull the field list from apex code, I'll live with that and add a non-rendered reference to markup. What the problem is:

 

<apex:inputField value="{!billItem.Hours__c}" required="true"/>

 

as you see, I DO HAVE the reference to the field in the markup and the standard controller is not picking this up, even though the algorithm should know that billItem is of GP_Bill_Item__c type, forcing me to double reference the field in the markup.

dchasmandchasman
Right - but take a closer look at what you are doing - you are pulling the object back through a custom apex code based getter or property get method, correct? This level of indirection via apex code is absolutely no different than the situation where you retrieve the sobject yourself via code. Essentially apex code is a black box as far as the standard controller is concerned here.
mmixmmix

Ok, so what you are saying is that I should reference a GP_BIll_Item__c.Hours__c in inputfield instead of billItem.Hours__c? That is kinda counterintuitive and brings confusion (referencing a type metadata instead of instance member). 

 

all the apex on the side, lets talk low level, you have an instance of controller class associated somehow to an extension class. Regardless of how you do the association you have the metadata for the extension class so its not really a blackbox for you, is it? I suspect you use Java so reflection is there and you most certainly know the type of billItem before you even instantiate the extension. Now I know what you will say, what if there is billItem2? Avoiding the ambiguity between different instances can most certainly be avoided by having a default named instance stemming from the controller, lets say a 'default', and then you would not even need an extension_XXX methods to tie everything manually. Or even better why not have extension class inherit the specific SObject controller and solve all the problems. 

 

Just my 2 cents, OOP has been around for decades, don't see why you had to go and complicate it.  

dchasmandchasman

GP_BIll_Item__c is a an instance member of the standard controller - we chose to use the name of the class as the name of the property that gets you to the root object because it is consistent with other areas in salesforce that set the precedent for this convention. There is most definitely a getGP_BIll_Item__c() accessor method on the SC class under the covers just like one that you would write in a custom controller. Alternate designs included using a this keyword approach but were not chosen for this reason.

 

As for the use of various design patterns we chose Mix In instead of IsA for a number of reasons - the main one being that implementation inheritance accross modules has also been a long understood anti pattern - suffers from fragile base class issues etc. IsA is typically not the correct relationship here - often extensions are used to aggregate in related but orthogonal functionality that is required by the presentation layer. The standard controller and its interaction with apex code has been made more and more sophisticated every release - e.g. you can now instantiate the SC and use it as a delegate in your code - something that was only recently made possible. Layer on top of all this the requirement that VF is supported in all sfdc editions - not all of which even have apex code authoring enabled/supported - and that the majority of "developers" using VF are not developers by trade and things get even more interesting... 

 

With all that said there is nothing stopping us from making something along the lines of an abstract StandardControllerBase system class in apex and allowing an apex code centric approach.To be honest you are the first personthat I am aware of to suggest this outside of salesforce R&D. I would strongly suggest that you create an idea on IdeaExchange and see if you can drum up some support...

 

Design patterns (and unfortunately anti patterns too) have been around since the begining of software and are in no way add odd with OOD/OOP concepts...

Message Edited by dchasman on 02-02-2009 08:39 AM
Message Edited by dchasman on 02-02-2009 08:46 AM
This was selected as the best answer
mmixmmix

Ok, 

thanks for taking the time to shed some light on this. As an architect just like yourself the whole apex concept was rubbing me the wrong way since I dwelved into it as I didnt really see the need for this pattern and was not always sure about the codeflow paths for extensions (and still am not entirely, you need some more in-depth docs for the likes of me). Although I am not sure why you think you'll have a weak base problem since you controll the base classes for SObjects and the inheritance will only go one level deep, but I am not going to go there any more :) I am the chicken, you guys are the pigs (no offense ;)) so its not right for me to comment when I was not there for your R&D sessions when you made decisions.

 

Thanks again. 

dchasmandchasman

Ah a fellow Scrum practionioner :-) I would not group any customer of VF in the "chicken" category (for those following along that are not familiar with Scrum terminology a chicken is someone not directly on the team). The last thing we want is to discourage open dialogs on stuff like this. Don't stop because I push back with a history lesson etc - we need to work together to make VF and Force.com better and better. I was quite serious about the suggestion to post your ideas to the IdeaExchange - this carries much more weight than you might imagine. Maybe too much at times (can suffer from sqeaky wheel syndrome) - but so far it has worked out very well as a vehicle for helping us prioritize what we do and when.

 

Can you tell me more about the areas you would like more in depth info on? BTW we are about to roll out some docs on the VF lifecycle - something a number of folks have been asking for so I worked with the VF tech writer to craft externally publishable content on this.

BrianWKBrianWK

dchasman,

 

I think I understand this thread - and it may apply to issue I've been having. Am I right that this would apply to multiple pages using the same standard controller/extension?

 

My specific instance is I have a very simple Page A - that only calls the Name of the Opportunity. On Page B (called by command button) uses most of the other fields we have available on the Opportunity.

 

Page B - throws me the SoQL error on Opportunity fields, unless I go back and add the field someplace on a page (included a nonrendered outpanel).

 

Is this an example of what's described here? The standard controller SoQL is only querying fields on the Page 1 and therefore wouldn't be available to display in page 2?

dchasmandchasman
Yes, this is a current limitation in the SC - the main issue is that there is no metadata that links the pages that might be traversed into a unit and requerying to accrete in more fields is not an option. Think about how you would solve this same set of issues with a custom controller and you'll see what I mean...