[SalesForce] Invalid field on sobject

Apex class:

public with sharing  class CallCentre{


    public String search { get; set; }

    public String searchquery { get; set; }
    public list<Contact> con{get;set;}
    public string searchstring {get;set;}
    public CallCentre(){ }
    public void search()
    {
      string query='SELECT Name, Units_1__c, Email , Phone, tenant_street__c, tenant_city__c,( SELECT   SVMXC__Problem_Description__c,Type_of_Order__c from SVMXC__Service_Order__r) from Contact where  Tenant_Street__c like \'%'+search+'%\' Limit 10';
      con=Database.query(query);
      system.debug('Con List'+con.size()+con);

Visualforce Page:

<apex:page controller="CallCentre" sidebar="false">
    <apex:form >
        <apex:pageBlock title="Contact Service Department"> 
            <apex:OutputText value=" Address : "/> 
            <apex:inputText label="Address" value="{!search}"/> 
            <apex:commandButton value="search" action="{!Search}" rerender="pbt"/> 
        </apex:pageBlock> 
        <apex:pageBlock title=" Search Results" >
            <apex:OutputText value="Ask the tenant:What unit you are In? Find the matching record, If no matching exists with information they provide tell them to confirm the name on the lease and to call back"/> 
            <apex:actionregion >
                <apex:pageBlockTable id="pbt" value="{! con}" var="c"> 
                    <apex:column value="{!c.Name}"/>
                    <apex:column value="{!c.Units_1__c}"/>
                    <apex:column value="{!c.Email}"/>
                    <apex:column value="{!c.phone}"/>
                    <apex:column value="{!c.Tenant_Street__c}"/>
                    <apex:column value="{!c.Type_of_order__r}"/>
                    <apex:column value="{!c.Tenant_City__c}"/> 
                </apex:pageBlockTable> 
            </apex:actionregion> 
        </apex:pageBlock> 
    </apex:form> 
</apex:page>

Best Answer

With so few details, it's difficult to isolate the problem.

That said, this seems to be a lack of basic understanding of how relationship queries work.

You say that the error occurs when you try to add <apex: column value="{! c.type_of_order__r}"/> to your Visualforce page. That should be your first clue that you can't treat this like any other field.

Let's look at your query. Formatted so things are easier to read...

SELECT 
    Name, Units_1__c, Email , Phone, tenant_street__c, tenant_city__c,
    (SELECT
        SVMXC__Problem_Description__c, Type_of_Order__c
    FROM 
        SVMXC__Service_Order__r
    ) 
FROM 
    Contact
WHERE 
    Tenant_Street__c like \'%'+search+'%\' Limit 10'

Issues with SOQL injection aside, a couple of things should be obvious:

  • You aren't querying a "type_of_order__r" field on the Contact
  • There is a "type_of_order__c" field in your subquery (a.k.a. Left Outer Join)

Your visualforce page is iterating over the Contact records returned by your query, and storing them in a temporary variable 'c'.

Since 'c' is a Contact, and you aren't querying a "type_of_order" field on Contact, I hope it's now obvious why you're getting an error.

The other thing you seem to be confused by is __r vs __c. The short (and not explained in-depth) version is that __c is used to reference custom fields, and __r is used to reference custom relationships.

Something ending in __r is either:

  • A reference to a single, nested SObject (in the case where you're traversing from child to parent)
  • A reference to a List of nested SObjects (in the case where you're traversing from parent to child)

Putting that all together now, <apex: column value="{! c.type_of_order__r}"/> is incorrect on several levels:

  • type_of_order__r is not a field on Contact
  • type_of_order__r is not a single field at all
  • type_of_order__r is not the correct way to reference a field on a child object, and if it were, <apex:column> cannot take an entire object as its value

The correct way to reference the type_of_order__c field is through the child relationship SVMXC__Service_Order__r. c.SVMXC__Service_Order__r will return a list of SVMXC__Service_Order__c records though, and <apex:column> can't handle that very well either.

In the end, you'll need to use another visualforce iteration tag (pageBlockTable, dataTable, or repeat)...something along the lines of

    <!-- other markup omitted -->
    <apex:column value="{!c.Tenant_Street__c}"/>
    <apex:repeat value="{!c.SVMXC__Service_Order__r}" var="child">
        <apex:outputField value="child.Type_of_order__c" />
    </apex:repeat>
    <apex:column value="{!c.Tenant_City__c}"/> 
</apex:pageBlockTable> 

And that's about as much information I can give you with the scant amount of detail that you've provided. In the future, remember that the more details you provide in your question, the better and more accurate the answers you can receive.

Related Topic