+ Start a Discussion
gregusagregusa 

Why does referencing the Record Type on a custom object throw a system error?

I have a custom controller for a custom object.  When I include this code on the visualforce page:

Code:
    <apex:pageBlockTable value="{!over}" var="a" id="table">  
        <apex:column headerValue="Record Type">                     
          <apex:
            <apex:inputField value="{!a.RecordType}" />
        </apex:column> 
     </apex:pageBlockTable> 

 I get the following error:

Code:
An internal server error has occurred
An error has occurred while processing your request. The salesforce.com support team has been notified of the problem. If you believe you have additional information that may be of help in reproducing or correcting the error, please contact support@salesforce.com. Please indicate the URL of the page you were requesting, any error id shown on this page as well as any other related information. We apologize for the inconvenience.

Thank you again for your patience and assistance. And thanks for using Salesforce!

Error ID: 1550134988-19307 (1773106477)

 
I'm having a hard time understanding coding for RecordTypes.  Can anyone point me in the right direction?

JimRaeJimRae
Not a good error message to say the least.
A few things I see.
First, are you retrieving the Recordtypeid field when you create the list called "over"
Second, RecordType is not the name of any field, so this would cause an error.
 you could use RecordType.Id, but, chances are, depending on your ultimate goal, that won't be enough.
If you are allowing the user to select the record type, you will want to create a select option list with the
possible record types for that object, and allow the user to select by name.  Also, note that since dependent picklists aren't supported
you will have to control which options are valid for the user programatically.

Here is a code snippet that will create a list of record types for the Account object, you could start with this:

Code:
String recType;
    public List<SelectOption> getrectypes() {
    List<SelectOption> options = new List<SelectOption>();
    options.add(new SelectOption('','--Select Record Type --'));
    for(RecordType rt:[select id,name from recordtype where sobjecttype='Account']){
            options.add(new SelectOption(rt.id,rt.name));
    }
    return options;
}
public String getRecordType() {
return recType;
}
public void setRecordType(String recType) {
this.recType= recType;
}

 
And the page:

Code:
<apex:selectList value="{!RecordType}" multiselect="false"  size="1">
            <apex:selectOptions value="{!rectypes}"/>
            </apex:selectList>

 

gregusagregusa
Thanks, I've been trying all kinds of things, including SelectOption -- and keep coming back to the same issue...

I don't understand how to bind the selected value from the SelectOption to the RecordTypeID of the custom object.  As you'll see below, I plugged in your code for RecordTypes, both in the Page and the Controller.  However when I try to save the code I get the following error:  Unknown property 'RecordType'.


Here's a scaled down version of my Visualforce page:


Code:
<apex:page controller="overrideInsertController" title="Insert Override">    
    <apex:form >        
    <apex:pageBlock>                    
        <apex:pageBlockButtons >                
            <apex:commandButton value="Save" action="{!save}" rerender="error,table"/>  
            <apex:commandButton value="Cancel" action="{!cancel}" rerender="error,table" immediate="true"/>          
        </apex:pageBlockButtons>                    
    <apex:pageBlockTable value="{!over}" var="a" id="table">  
        <apex:column headerValue="Record Type">                      
   <apex:selectList value="{!RecordType}" multiselect="false"  size="1">
             <apex:selectOptions value="{!rectypes}"/>
            </apex:selectList>             
        </apex:column>                                    
        <apex:column headerValue="Override Date">                      
            <apex:inputField value="{!a.Override_Date__c}" required="true" />                          
        </apex:column>
        <apex:column headerValue="Override Amount">                    
            <apex:inputField value="{!a.Override_Amount__c}" required="true" />                           
        </apex:column>                                          
     </apex:pageBlockTable>                         
    </apex:pageBlock>    
    </apex:form>
</apex:page>

 and the Controller...

Code:
public class overrideInsertController{ 
      
    public List<Override__c> over{get; set;}         
      
 String recType;
 
    public List<SelectOption> getrectypes() {
     List<SelectOption> options = new List<SelectOption>();
     options.add(new SelectOption('','--Select Record Type --'));
     for(RecordType rt:[select id,name from RecordType where sobjecttype='Override__c']){
            options.add(new SelectOption(rt.id,rt.name));    
    }
     return options;
 }
 
 public String getRecordType() {
  return recType;
 }
 
 public void setRecordType(String recType) {
  this.recType= recType;
 }
        
    public overrideInsertController(){          
        over= new List<Override__c>();        
        over.add(new Override__c());    
    }               

    public PageReference save(){     
        insert over;           
    }
 
}

 
This is why I went back to just the input field wondering if I was trying to make this too difficult.  Now I see that RecordTypeID is a "reference field" on my object "Override__c", which is a different type from all of the other fields I've successfully been working with, so I started thinking maybe there was some special technique for dealing with Record Types.


JimRaeJimRae
Greg,
It is odd that you get that error when saving the apex code.  That would imply that you don't have visibility to the RecordType object in your org.  Do you?  Can you see the RecordType object using something like the Apex Explorer, or even the schema viewer in Eclipse?
Correcting this issue is your first order of business.
Your other option would be to get the recordtypeid's yourself, and manually build the select option list.

Now, as for binding this select result into your record when saving, this is what I would do.

Change your Save code like this:

Code:
public PageReference save(){     
    //make sure some value was selected for the record type
    if(recType.length()>0){
        over.recordtypeid=recType;
        insert over;           
    }else{
        ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR, 'Record Type must be selected');      
        
    }
    }

you will need to add a message tag to your selectlist component to display the error if the user didn't select any value.
 

gregusagregusa
Yes I can see the RecordType object using the Schema viewer in Eclipse.  Still haven't figured that out.

However, problem with the save syntax you gave me:

Code:
    public PageReference save(){     
//make sure some value was selected for the record type
if(recType.length()>0){
(this is line 45): over.recordtype=recType;
insert over;
}else{
ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR, 'Record Type must be selected');
}
}
 
I get the following error when trying to save that to the server:   Save error: Initial term of field expression must be a concrete SObject: LIST:SOBJECT:Override__c (line 45)
JimRaeJimRae
Sorry, I don't have your custom object to work with, I am trying to do this from memory.

your line 45 should read:

over.recordtypeid = recType;
gregusagregusa
I also tried
over.recordtypeid=recType;
but got the same error...
JimRaeJimRae
I think I see the issue now, you are declaring Over as an array of records.  you need to search the forums for examples of selectlists used in an array of values.  I know the issue is that the variables all have the same name, but I don't recall what the solution is.  If your user would alway pick the same record type for each, you could move the recordtypeid outside of the pageblocktable and get the value there, and just use it for every record you are inserting.
for testing, you could say over[0].recordtypeid = recType;
just to see if it works with one record in the array.
gregusagregusa
Thanks Jim. This put me over the top.  I get it now.  Thanks for sticking with it!