+ Start a Discussion
Zoom_VZoom_V 

SObject row was retrieved via SOQL without querying the requested field:

I am getting this error when I go into Edit mode for a record. I'm using the same controller & VF page that I am using for a New record of the same object. 

SObject row was retrieved via SOQL without querying the requested field: Contract_Overview__c.Contract_Start_Date__c 

 

 

I thought it would solve the problem to retrieve the field in my query  (such as Name and Contract_Type_c) - but then I just get the same error for the next field which is included as an input field in the VF page. I guess I could solve the whole problem by just retrieving EVERY single field which is an input field in the VF page, but I don't want to have to do that. There's gotta be a better way. 

 

Here is the controller being used : 

 

public class MycontrollerSFDCBETA2{

    public String rightOptionsHidden { get; set; }

    public String leftOptionsHidden { get; set; }

    public MycontrollerSFDCBETA2() {

    }

    public Account selectedUser { get; set; }
    String contractid;
    public Contract_Overview__c contract{get;set;}
    public string relatedAccount{get;set;}
    public string names{get;set;}
    public string accountid{get;set;}
    public Name contractnew{get;set;}
    public string selectedaccountid{get;set;}
    public String message { get; set; }

    public List<SelectOption> selectedContacts { get; set; }
    public List<SelectOption> options { get; set; }

    public MycontrollerSFDCBETA2(apexpages.standardcontroller controller)
        {
        selectedContacts = new list<SelectOption>();
        contract = new Contract_Overview__c();
        contractid=system.currentpagereference().getparameters().get('id');
            if(contractid!=null)
            {
                contract=[select account__c,Name,Contract_Type__c,  Subsidiaries_On_Contract__c from Contract_Overview__c  where id =:contractid];
                relatedAccount=Contract.account__C;
            }
        }

    public pageReference  execute()
        {
        accountid=contract.Account__c;
        System.debug('########'+accountid);
        return null;
        }

    public list<selectoption> getitems()
        {
        
        List<selectoption> options= new list<selectoption>();
                    
        if(accountid != null)
            {
                account a =[select name , (select name from Subsidiaries_and_Brands__r) from account where id =:accountid];
        for(SubsidiariesAndBrands__c s : a.Subsidiaries_and_Brands__r)
                    {
                    options.add(new SelectOption(s.name,s.name));
                    }
            }
        else
            options.add(new SelectOption('None','None'));
            return options;
            
        }
            
    public void save()
        {
        
        System.debug('********************************' + names);
        
        message = null ;       
        Boolean first = true;
        for ( SelectOption so : selectedContacts ) {
            if (first) {
                message = message ;
            }
            
                
            message = message + ', ' + so.getValue() ;
            
            first = false;
            
        }
        
        message=message.removeStart('null, ');
        message='['+message+']';
        
        System.debug('********************************' + message);
        contract.Subsidiaries_On_Contract__c=message;
        
        insert contract;
        contract=new Contract_Overview__c  ();
        System.debug('********************************' + contract);
                  
        }
}

 

and here's part of the VF page : 

 

<apex:outputLabel value="Contract Overview Name : "/>
                    <apex:inputfield value="{!contract.Name}" />
                    <apex:outputfield value="{!contract.OwnerId}"/>
                    <apex:outputLabel value="Contract Type : "/>
                    <apex:inputfield value="{!contract.Contract_Type__c}" required="false"/><br></br>
                    <apex:outputLabel value="Contract Status : "/>
                    <apex:inputfield value="{!contract.Contract_Status__c}" required="false"/><br></br>
                    <apex:outputLabel value="Contract Start Date : "/>
                    <apex:inputfield value="{!contract.Contract_Start_Date__c}" required="false"/><br></br>

 

 

 

So, in other words, if I retrieve Status__c in the query I'll just get that same sObject error for Contract_Start_Date__c and so on and so on...

I'm sure there's gotta be a better way than this. Anybody know them ? 

Thank you very much for your help.

 

Best Answer chosen by Admin (Salesforce Developers) 
ForcepowerForcepower
I still think you can get rid of this:
contractid=system.currentpagereference().getparameters().get('id');
if(contractid!=null)
{
contract=[select account__c,Subsidiaries_On_Contract__c,Name,Contract_Type__c, Contract_Status__c from Contract_Overview__c where id =:contractid];
relatedAccount=Contract.account__C;
}

If you need it solely for Contract.account__C, I'd suggest making a hidden variable for that field on your VF page.
<apex:outputText value="{!contract.account__C}"
rendered="false"/>

That will force getController() to bring it back and then you can just access it from contract and have it available for your Select List.

All Answers

hitesh90hitesh90

Hi,

 

try this code. this error is because of you haven't written Contract_Start_Date__c field in your SOQL query.

 

public class MycontrollerSFDCBETA2{

    public String rightOptionsHidden { get; set; }

    public String leftOptionsHidden { get; set; }

    public MycontrollerSFDCBETA2() {

    }

    public Account selectedUser { get; set; }
    String contractid;
    public Contract_Overview__c contract{get;set;}
    public string relatedAccount{get;set;}
    public string names{get;set;}
    public string accountid{get;set;}
    public Name contractnew{get;set;}
    public string selectedaccountid{get;set;}
    public String message { get; set; }

    public List<SelectOption> selectedContacts { get; set; }
    public List<SelectOption> options { get; set; }

    public MycontrollerSFDCBETA2(apexpages.standardcontroller controller)
        {
        selectedContacts = new list<SelectOption>();
        contract = new Contract_Overview__c();
        contractid=system.currentpagereference().getparameters().get('id');
            if(contractid!=null)
            {
                contract=[select account__c,Name,Contract_Type__c,  Subsidiaries_On_Contract__c,Contract_Start_Date__c from Contract_Overview__c  where id =:contractid];
                relatedAccount=Contract.account__C;
            }
        }

    public pageReference  execute()
        {
        accountid=contract.Account__c;
        System.debug('########'+accountid);
        return null;
        }

    public list<selectoption> getitems()
        {
        
        List<selectoption> options= new list<selectoption>();
                    
        if(accountid != null)
            {
                account a =[select name , (select name from Subsidiaries_and_Brands__r) from account where id =:accountid];
        for(SubsidiariesAndBrands__c s : a.Subsidiaries_and_Brands__r)
                    {
                    options.add(new SelectOption(s.name,s.name));
                    }
            }
        else
            options.add(new SelectOption('None','None'));
            return options;
            
        }
            
    public void save()
        {
        
        System.debug('********************************' + names);
        
        message = null ;       
        Boolean first = true;
        for ( SelectOption so : selectedContacts ) {
            if (first) {
                message = message ;
            }
            
                
            message = message + ', ' + so.getValue() ;
            
            first = false;
            
        }
        
        message=message.removeStart('null, ');
        message='['+message+']';
        
        System.debug('********************************' + message);
        contract.Subsidiaries_On_Contract__c=message;
        
        insert contract;
        contract=new Contract_Overview__c  ();
        System.debug('********************************' + contract);
                  
        }
}

 

Important :
Hit Kudos if this provides you with useful information and if this is what you where looking for then please mark it as a solution for other benefits.

Thanks,
Hitesh Patel

ForcepowerForcepower
Zoom, Instead of doing an explicit query, can you not just do a getRecord on the standard controller to get your record? I would think the standard controller would bring back all the fields you need.
contract = controller.getRecord();
Try that and see if that works for you.
Ram
Zoom_VZoom_V

Ram :

 

Thank you very much for your response. That sounds exactly like what I need. But are you sure it would properly fit into this code ? I guess I need a line like this some where : 

public contract getRecord(String criteria);

 

and then some change to the query like this  : (?)

public MycontrollerSFDCBETA2(apexpages.standardcontroller controller)
        {
        selectedSubs = new list<SelectOption>();
        contract = new Contract_Overview__c();
        contractid=system.currentpagereference().getparameters().get('id');
            if(contractid!=null)
            {
                return=[select account__c,Subsidiaries_On_Contract__c,Name,Contract_Type__c, Contract_Status__c from Contract_Overview__c  where id =:contractid];
                relatedAccount=Contract.account__C;
            }
        }

 


...but I can't figure out how it should fit into the code since contract is being declared as a New Contract_Overview__c. 

Thank you very much for your help.

Zoom_VZoom_V

hitesh : 

Yes, I know I could continuously retrieve each field explicitly through the query, but I don't want to do that because I have so many fields.

I think Ram is on to the solution. I just need to figure that getrecord method into my particular code.

 

Thanks again

ForcepowerForcepower
Zoom,

No need to define getRecord. You get it as a method on the standard controller.


Just do this:
contract = controller.getRecord();

You can comment out the following lines:
/*
contract = new Contract_Overview__c();
contractid=system.currentpagereference().getparameters().get('id');
if(contractid!=null)
{
return=[select account__c,Subsidiaries_On_Contract__c,Name,Contract_Type__c, Contract_Status__c from Contract_Overview__c where id =:contractid];
relatedAccount=Contract.account__C;
}
}
*/
Zoom_VZoom_V

Ram,

 

How can I comment out all of those lines ? I need the query. 

 

Thank you.

ForcepowerForcepower
Zoom,

controller.getRecord() will do the querying for you and bring back the fields needed by your VF page. Please give that a try and see how it goes.
Ram
SurpriseSurprise

Check below given link with an example on how getrecord() funstions

 

http://www.salesforce.com/us/developer/docs/pages/Content/apex_pages_standardcontroller.htm

BritishBoyinDCBritishBoyinDC

To add to the post above, if you are using the Standard Controller, and this class is an extension, then it would look something like this and you wouldn't need to query for fields linked to the main object referenced by the Standard Controller:

 

public class MycontrollerSFDCBETA2{

private final Contract_Overview__c contract;

		public MycontrollerSFDCBETA2 (ApexPages.StandardController stdController) {
		
		// The extension constructor initializes the private member 
		//variable by using the getRecord method from the standard controller.

		this.contract = (Contract_Overview__c)stdController.getRecord();
		
		//Anything else
		selectedContacts = new list<SelectOption>();
		
		
		} //end constructor
		
        }

 

Zoom_VZoom_V

BritishBoy & Ram,

 

Thanks again for all of your help. I really appreciate it. 

Ram : 

 

I think I may have confused you because I was incorrectly taking the values from the query and putting them into the input values in the VF, and that's not what I meant to do. Your getrecord() solution is def what I need, but I also need the query because that is how I am gathering the values for my SelectList on the current record. 

 

...or maybe I'm confused, which wouldn't be a first

BritishBoy :

Thank you very much for elaborating on the getRecord() solution. 

 

I am trying to apply your recommendations to my code and I'm wondering if you (or Ram) could help me with these errors. Here is the code as it is right now : 


public class MycontrollerSFDCBETA2{

private final Contract_Overview__c contract;

    public String rightOptionsHidden { get; set; }

    public String leftOptionsHidden { get; set; }

    public MycontrollerSFDCBETA2() {

    }

    public Account selectedUser { get; set; }
    String contractid;
    
    public string relatedAccount{get;set;}
    public string names{get;set;}
    public string accountid{get;set;}
    public Name contractnew{get;set;}
    public string selectedaccountid{get;set;}
    public String message { get; set; }

    public List<SelectOption> selectedSubs { get; set; }

    public List<SelectOption> options { get; set; }

    public MycontrollerSFDCBETA2(apexpages.standardcontroller controller)
   
        {
        this.contract = (Contract_Overview__c) stdController.getRecord();
        
        selectedSubs = new list<SelectOption>();
        
        contractid=system.currentpagereference().getparameters().get('id');
            if(contractid!=null)
            {
                contract=[select account__c,Subsidiaries_On_Contract__c,Name,Contract_Type__c, Contract_Status__c from Contract_Overview__c  where id =:contractid];
                relatedAccount=Contract.account__C;
            }
        }

    public pageReference  execute()
        {
        accountid=contract.Account__c;
        System.debug('########'+accountid);
        return null;
        }

    public list<selectoption> getitems()
        {
        
        List<selectoption> options= new list<selectoption>();
                    
        if(accountid != null)
            {
                account a =[select name , (select name from Subsidiaries_and_Brands__r) from account where id =:accountid];
        for(SubsidiariesAndBrands__c s : a.Subsidiaries_and_Brands__r)
                    {
                    options.add(new SelectOption(s.name,s.name));
                    }
            }
        else
            options.add(new SelectOption('None','None'));
            return options;
            
        }
            
    public void save()
        {
        
        System.debug('********************************' + names);
        
        message = null ;       
        Boolean first = true;
        for ( SelectOption so : selectedSubs ) {
            if (first) {
                message = message ;
            }
            
                
            message = message + ', ' + so.getValue() ;
            
            first = false;
            
        }
        
        message=message.removeStart('null, ');
        message='['+message+']';
        
        System.debug('********************************' + message);
        contract.Subsidiaries_On_Contract__c=message;
        
        insert contract;
        contract=new Contract_Overview__c  ();
        System.debug('********************************' + contract);
                  
        }
}

 and right now I'm getting this error : 

Error: Compile Error: Method does not exist or incorrect signature: standardcontroller.getRecord() at line 30 column 48

 

for this line : 

this.contract = (Contract_Overview__c) stdController.getRecord();

 

Thank you very much for all of your help.

 

 

 

ForcepowerForcepower
Zoom, Got it. Here's the issue:
stdController.getRecord(); - change this to
controller.getRecord(); //controller is the name of your paremeter into the method

Also, you my want to do your query retrieval into a separate variable for contract, may be contract2. I don't understand the purpose of that second query totally but if you really need it, assign it to a different variable. Otherwise you end up overwriting what controller.getRecord() retrieved and essentially the same original error you started with. Let me know if that makes sense.
Ram
ForcepowerForcepower
I still think you can get rid of this:
contractid=system.currentpagereference().getparameters().get('id');
if(contractid!=null)
{
contract=[select account__c,Subsidiaries_On_Contract__c,Name,Contract_Type__c, Contract_Status__c from Contract_Overview__c where id =:contractid];
relatedAccount=Contract.account__C;
}

If you need it solely for Contract.account__C, I'd suggest making a hidden variable for that field on your VF page.
<apex:outputText value="{!contract.account__C}"
rendered="false"/>

That will force getController() to bring it back and then you can just access it from contract and have it available for your Select List.
This was selected as the best answer
BritishBoyinDCBritishBoyinDC

I'm with Ram on this one - not sure why you are keeping the query code in the constructor?

 

Just to clarify - for the code I posted to work, the page calling it needs to be invoking the Standard Controller for the object, and then invoking your class as an extension i.e.

 

apex:page StandardController = "Contract_Overview__c" Extensions = "MycontrollerSFDCBETA2"

In that way, you are invoking the standard behavior for that custom object - in the same way as if you clicked new or view or edit. Any page invoked that references a standard controller looks for a query param of Id=xxx and queries for that record. If it is blank, it replicates the New functionality. 

 

As such, you don't need to then query for a record if you are editing an existing one - the standard controller will take care of that for you. And any fields visible on the page for that object are automatically included in the SOQl invoked for that page.

 

 

Zoom_VZoom_V

That worked ! Thanks so much you guys !

 

Also : You two are right : I can take that whole query out. I totally misread that whole thing. Sorry about that Ram, I was not thinking properly and for some reason was thinking of the other query pulling the related Accounts.

 

Thank you so much you two !

 

One of the things that I need to do is this : This is now an altered version of the class I'm using for newly created records. So, since this will be used for Edit I want to populate that !items automatically since it doesn't really need to wait for the user to choose an Account__c. 

 

I know it is in this part of the code, but I can't see how to reference the already populated field : 

    public MycontrollerSFDCBETA2b(apexpages.standardcontroller controller)
   
        {
        this.contract = (Contract_Overview__c) controller.getRecord();
        
        //controller.getRecord(); //controller is the name of your paremeter into the method
        
        selectedSubs = new list<SelectOption>();
       
        }

    public pageReference  execute()
        {
        accountid=contract.Account__c;
        System.debug('########'+accountid);
        return null;
        }

    public list<selectoption> getitems()
        {
        
        List<selectoption> options= new list<selectoption>();
                    
        if(accountid != null)
            {
                account a =[select name , (select name from Subsidiaries_and_Brands__r) from account where id =:accountid];
        for(SubsidiariesAndBrands__c s : a.Subsidiaries_and_Brands__r)
                    {
                    options.add(new SelectOption(s.name,s.name));
                    }
            }
        else
            options.add(new SelectOption('None','None'));
            return options;
            
        }

 

Also, is there a way I could populate the selectedSubs column with the values already selected in SubsidiariesAndBrands__c ?

Thanks so much you two. I really appreciate it. 

 

 

ForcepowerForcepower
Zoom - you're very welcome. You can just put that statement in getItems as well:
public list<selectoption> getitems()
{

accountid=contract.Account__c;


-----------------------------
As far as preselecting certain values, you can do it by setting the value/s on your selectedItem variable. You could do it within getItems - assuming I understood your question correctly.

<apex:selectList value="{!selectedItem}" size="1">
Zoom_VZoom_V

Ram,

 

Is there an easy way to make the right column options = contract.Subsidiaries_On_Contract__c ? Right now, I'm using selectedSubs as the value, but I can't assign a String to that. I think I need to convert the string into a SelectOption list somehow. How can I do that ? 

 

Thanks again.

ForcepowerForcepower
Zoom, Are you asking how you would pre-select contract.Subsidiaries_On_Contract__c in selectedSubs? Also, is this a single select or a multi select?
Ram
Zoom_VZoom_V

yes, that's exactly what I'm asking. It's a multi-select picklist.

 

Since this will be an editing I would like the already selected choices (Subsidiaries_On_Contract__c) to be put into the right option picklist (selected items). I am currently assigning selectedSubs to the rightOptions, so I figured it would be good to automatically put those field values in there so the user won't have to re-select them when editing.

 

Thanks again !

ForcepowerForcepower
Zoom,

The simplest way would be to display the multi select as an inputField and have VF manage it. Something like this. Make sure you expose account as a variable available to the page.

<apex:inputField value="{!account.SubsidiariesAndBrands__c}" />

If you're managing the selected and unselected lists yourself, let me know. That would involve assigning something like this to your selected list value
[value1, value2, value3]
Ram
Zoom_VZoom_V

Yes, I'm managing the selected and unselected values myself in a dual-column setup. That's actually what my query is doing in the controller. So, I'm automatically assigning !items from the query results to the unselected column(left) picklist, and initially assigning what is a blank list (selectedSubs) to the selected column(right). That works when making a new record. However, when editing I would like to bring the values already selected into the selected column(right) so the user won't have to re-select them when saving an edit.

 

I wish it was just as easy as putting a picklist in the VF page. 

 

Thanks Ram

ForcepowerForcepower

ok, Zoom. I assume you're querying and getting the values that need to be pre-selected. Try printing that field - I believe it would be a semi-colon delimited string.Let's say you assign it to preSelValueStr. Here's what you do:


                String[] preSelValues = preSelValueStr.split(';');
                 for (String preSelVal: preSelValues) {
                // create a select option and add it to your preselected option list

 

                }

Ram

Zoom_VZoom_V

Ram,

 

I know this is pathetic, but can you tell me where I would go with this code ?

public String selectedMulPickKeyTech{get;set;} 
public List<SelectOption> selectedSubs { get; set; }

selectedMulPickKeyTech=contract.Subsidiaries_On_Contract__c;

String[] selectedvalues = selectedMulPickKeyTech.split(';')

	for (String selectedvalues: selectedvalues) {
		List <SelectOption> selectedSubs = new list<SelectOption>();
 		selectedSubs.add(new SelectOption(selectedvalues,selectedvalues));
	}

 

I know that's not right, but I'm trying to put it together. 

 

I know I'm asking a lot here. I really appreciate any help you can give.

 

Thank you.

 

ForcepowerForcepower

Zoom,

 

You're almost there. Minor correction:

 

 

public String selectedMulPickKeyTech{get;set;} 
public List<SelectOption> selectedSubs { get; set; }

selectedMulPickKeyTech=contract.Subsidiaries_On_Contract__c;

String[] selectedvalues = selectedMulPickKeyTech.split(';')

// selecteValue is one item in the list selectedvalues for (String selectedvalue: selectedvalues) { List <SelectOption> selectedSubs = new list<SelectOption>(); selectedSubs.add(new SelectOption(selectedvalue,selectedvalue)); }
ForcepowerForcepower

Sorry - one more correction: selectedSubs definition should be outside the loop.

 

public String selectedMulPickKeyTech{get;set;} 
public List<SelectOption> selectedSubs { get; set; }

selectedMulPickKeyTech=contract.Subsidiaries_On_Contract__c;

String[] selectedvalues = selectedMulPickKeyTech.split(';')
List <SelectOption> selectedSubs = new list<SelectOption>();
// selecteValue is one item in the list selectedvalues for (String selectedvalue: selectedvalues) { selectedSubs.add(new SelectOption(selectedvalue,selectedvalue)); }
Zoom_VZoom_V

I sent you a private message. Thank you Ram.

ForcepowerForcepower

Zoom,

Make sure selectedSubs2 is defined at the top of the controller like this:
public List <SelectOption> selectedSubs2 {get; set;}

 

// getItems


String[] selectedvalues = selectedMulPickKeyTech.split(';');

// initialize selectedSubs2

selectedSubs2 = new list<SelectOption>();
        // selecteValue is one item in the list selectedvalues
for (String selectedvalue: selectedvalues) {
     selectedSubs2.add(new SelectOption(selectedvalue,selectedvalue));
    }

Give that a shot and see how it goes.

Ram

Zoom_VZoom_V

That did it ! You're the man !

 

Thanks so much Ram. I appreciate it so much !

ForcepowerForcepower
Excellent. Glad to hear it. You're very welcome, Zoom.
Ram