0

I'm having a problem displaying lead information from a custom controller extension. The class looks like this:

public class LeadDuplicateManagement{
    public List<Lead> similarLeads { get; private set; }
    public Lead currentlead { get; set;} 
    private ApexPages.StandardController ctrl;

    //initialize class with standard controller parameter
    public LeadDuplicateManagement(ApexPages.StandardController stdController){
        ctrl = stdController;
        currentlead = (Lead)ctrl.getRecord();
        String id = currentLead.Id;
        String ownerFirstName = currentlead.Owner_First_Name__c;
        String ownerLastName = currentlead.Owner_Last_Name__c;
        similarLeads = [SELECT ID, Owner_First_Name__c, Owner_Last_Name__c, Phone1__c, Phone2__c, Phone3__c  
                                 FROM Lead 
                                 WHERE Owner_First_Name__c = :ownerFirstName
                                 AND Owner_Last_Name__c = :ownerLastName
                                 AND id != :id];
    }
}

If I do the below for visualforce markup, everything works fine:

<apex:page StandardController = "Lead" extensions = "LeadDuplicateManagement" >
{!currentlead.Owner_First_Name__c} {!currentlead.Owner_Last_Name__c} {!currentlead.Phone1__c} {!currentlead.id} {!lead.Owner_First_Name__c} {!lead.Owner_Last_Name__c} {!lead.Phone1__c} {!lead.Phone2__c} {!lead.Phone3__c}
etc...

However everything breaks and throws an error if I just do this instead:

<apex:page StandardController = "Lead" extensions = "LeadDuplicateManagement" >
{!currentlead.Owner_First_Name__c} {!currentlead.Owner_Last_Name__c} 
etc...

The error thrown is

System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Lead.Owner_First_Name__c

Why do I get this error? How can I fix it?

2
  • 1
    Your first and second markup snippets look very similar. What is the difference between them? Is it actually just that you reference fewer fields?
    – Adrian Larson
    Feb 21, 2019 at 0:11
  • Yes, Adrian. Exactly.
    – James
    Feb 21, 2019 at 16:12

1 Answer 1

1

There's a bit of almost-magic machinery between the Visualforce page and its associated standard controller.

When you include a direct reference to an sObject field in your Visualforce markup via the Lead. path, this establishes a dependency between your page and that field's content in the object that's managed by the standard controller. The standard controller "knows" to pull that field based upon the presence of that reference in your markup.

But currentlead is just some random sObject member variable in your controller extension, as far as Visualforce is concerned. Reference to its fields in page markup don't do anything for the standard controller, so it doesn't know to query those fields.

Hence, when you do not include the static reference {!lead.Owner_First_Name__c} in your page markup, and then your Apex controller does

String ownerFirstName = currentlead.Owner_First_Name__c;

you get your SObjectException - that field was never queried, because the standard controller didn't know you wanted it.

If you need to, you can add references for the standard controller to pick up on programmatically by calling addFields() with a list of the field names you need. Note that

This method should be called before a record has been loaded—typically, it's called by the controller's constructor. If this method is called outside of the constructor, you must use the reset() method before calling addFields().

You also can't call it in test context, so you may need to gate with if (!Test.isRunningTest()). It's easier if you can simply contrive your page's markup to grab the fields for you, since here, currentlead is the same record.

You must log in to answer this question.

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