[SalesForce] Implementing Save in Custom Controller

I have a custom object and a custom controller for it. I'm trying to have the controller save a newly-entered version of the object. This works if I just let the standard controller handle things, but I can't make the custom controller do it. I get the following message:

System.ListException: DML statement found null SObject at position 0

Here's a shortened version of the Visualforce page:

<apex:page Controller="ScholarRequestController">
<apex:pageMessages />
<apex:form >
<apex:pageBlock >
<apex:pageBlockSection >
<apex:inputField label="First Name:" value="{!ScholarToAdd.First_Name__c}" />
<apex:inputField label="Last Name:" value="{!ScholarToAdd.Last_Name__c}" />    
<apex:inputField label="Parent first Name:" value="{!ScholarToAdd.Parent_First_Name__c}" />
...         
</apex:pageBlockSection>   
   <apex:pageBlockButtons >
       <apex:commandButton action="{!save}" value="Save"/>
...  

Here's the relevant bits of the constructor and save function:

public ScholarRequest__c ScholarToAdd{get;set;}
...
public void ScholarRequestController(ApexPages.StandardController stdController){

SR_ID = ApexPages.currentPage().getParameters().get('id');

ScholarToAdd =  (SR_ID == null) ?      
new ScholarRequest__c() : 
    [Select Name,
    First_Name__c,
    Last_Name__c,
    Parent_First_Name__c,
    Parent_Last_Name__c,
    Grade__c,
    Cluster__c,
    Scholar_Start_Date__c,
    Date_of_Birth__c,
    Student_ID__c,
    Phone_Number__c
     From ScholarRequest__c
     where ID = :SR_ID];
....
public PageReference save() {
    List<ScholarRequest__c> sl = new List<ScholarRequest__c>();
    sl.add(ScholarToAdd);
    Try{                                                              

        insert(sl);
....

What am I doing wrong? BTW, the general model I used for this page and controller is here. The example uses upsert instead of insert. I get the same message either way.

Best Answer

I figured out what I did wrong (short version - copy and paste coding will likely be the death of me some day).

To save a bit of typing, I copied a constructor from a controller extension that had some code I needed. It had the signature you see here:

public void ScholarRequestController(ApexPages.StandardController stdController){

What it needed to have was the following signature:

public ScholarRequestController(){

If your constructor signature is not correct, a default constructor gets called behind the scenes. Once the signature was correct, my code worked as intended. It took me a while to realize this as the constructor results end up in a separate log file from the save results. This is, of course, to be expected, but sometimes I forget the log results don't all go to the same file.

Related Topic