function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
eliotstockeliotstock 

custom controller's setter method is never called before save()

Hi there

 

I have a form with some inputField tags on a page that uses a custom controller. I would expect the setter method for the field to be called on my controller before save() is called, but this doesn't happen.

 

page:

 

 

<apex:page controller="MetricController"> <apex:sectionHeader title="Metric Creation" /> <apex:form > <apex:pageBlock mode="edit"> <apex:pageMessages /> <apex:pageBlockButtons > <apex:commandButton action="{!save}" value="Save"/> <apex:commandButton action="{!cancel}" value="Cancel" immediate="true"/> </apex:pageBlockButtons> <apex:pageBlockSection title="Information" columns="2"> <apex:inputField value="{!metric.Metric_Definition__c}" required="true"/> <apex:inputField value="{!metric.Starting_Value__c}" /> <!-- etc --> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>

 and controller:

 

 

public class MetricController { private Metric__c metric; private Metric_Definition__c metricDefinition; private String debug = ''; public MetricController() { this.metric = new Metric__c(); debug += 'new, empty Metric Definition Id: ' + this.metric.Metric_Definition__c; this.metricDefinition = new Metric_Definition__c(); } public Metric__c getMetric() { return this.metric; } public void setMetric(Metric__c metric) { debug += ', setMetric() called with a metric that has a metric definition with id: ' + metric.Metric_Definition__c; this.metric = metric; } public Metric_Definition__c getMetricDefinition() { return this.metricDefinition; } public void setMetricDefinition(Metric_Definition__c metricDefinition) { this.metricDefinition = metricDefinition; } public PageReference save() { Id defId = this.metric.Metric_Definition__c; debug += ', same Id but within save(): ' + defId; String notes = this.metric.Data_Collection_Notes__c; debug += ', notes: ' + notes; // Poor man's debug System.assert(false, debug); String accountId = ApexPages.currentPage().getParameters().get('AccountId'); this.metric.Organization__c = accountId; insert this.metric; return new PageReference('/' + metric.Id); } }

 

 In my debug I never see the text I add during the call to the setter. Any ideas?

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
Ron HessRon Hess

the setter that gets called is built into the sobject metric__c, so once the page calls getMetric() it has all it needs to do the binding.

 

here is a modified page/controller and the debug output

 

public class MetricController { private Account metric; public MetricController() { this.metric = new Account(); System.debug( 'new, empty Metric Definition Id: ' + this.metric.Description); } public Account getMetric() { return this.metric; } public void setMetric(Account metric) { System.debug(' setMetric() called with a metric that has a metric definition with id: ' + metric.Description); this.metric = metric; } public PageReference cancel() { return null; } public PageReference save() { System.debug(', same Id but within save(): ' + this.metric); String accountId = ApexPages.currentPage().getParameters().get('AccountId'); this.metric.description = accountId; insert this.metric; return new PageReference('/' + metric.Id); } }

 

 

<apex:page controller="MetricController"> <apex:sectionHeader title="Metric Creation" /> <apex:form > <apex:pageBlock mode="edit"> <apex:pageMessages /> <apex:pageBlockButtons > <apex:commandButton action="{!save}" value="Save"/> <apex:commandButton action="{!cancel}" value="Cancel" immediate="true"/> </apex:pageBlockButtons> <apex:pageBlockSection title="Information" columns="2"> <apex:inputField value="{!metric.Name}" required="true"/> <apex:inputField value="{!metric.Description}" required="true"/> <apex:inputField value="{!metric.Rating}" /> <!-- etc --> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>

 

 

 

 

now output, note that the values i typed into the page are available inside the save() with no work required on my part, and the setter is not called.

 

 

***Begining Page Log for /apexpages/devmode/developerModeContainer.apexp 20090513185815.219:External entry point: returning SOBJECT:Account from method public SOBJECT:Account getMetric() in 0 ms 20090513185815.219:Class.MetricController.save: line 23, column 9: , same Id but within save(): Account:{Name=sdfdsf, Description=sdfdfs} 20090513185815.219:Class.MetricController.save: line 27, column 9: Insert: SOBJECT:Account 20090513185815.219:Class.MetricController.save: line 27, column 9: DML Operation executed in 43 ms 20090513185815.219:External entry point: returning NULL from method public System.PageReference save() in 45 ms Element j_id32 called method {!save} returned type PageReference: none20090513185815.219:External entry point: returning SOBJECT:Account from method public SOBJECT:Account getMetric() in 0 ms Cumulative profiling information: No profiling information for SOQL operations. No profiling information for SOSL operations. 1 most expensive DML operations: Class.MetricController.save: line 27, column 9: Insert: SOBJECT:Account: executed 1 time in 43 ms 2 most expensive method invocations: Class.MetricController: line 21, column 26: public System.PageReference save(): executed 1 time in 45 ms Class.MetricController: line 10, column 20: public SOBJECT:Account getMetric(): executed 2 times in 0 ms

 


 

 

All Answers

Ron HessRon Hess

the setter that gets called is built into the sobject metric__c, so once the page calls getMetric() it has all it needs to do the binding.

 

here is a modified page/controller and the debug output

 

public class MetricController { private Account metric; public MetricController() { this.metric = new Account(); System.debug( 'new, empty Metric Definition Id: ' + this.metric.Description); } public Account getMetric() { return this.metric; } public void setMetric(Account metric) { System.debug(' setMetric() called with a metric that has a metric definition with id: ' + metric.Description); this.metric = metric; } public PageReference cancel() { return null; } public PageReference save() { System.debug(', same Id but within save(): ' + this.metric); String accountId = ApexPages.currentPage().getParameters().get('AccountId'); this.metric.description = accountId; insert this.metric; return new PageReference('/' + metric.Id); } }

 

 

<apex:page controller="MetricController"> <apex:sectionHeader title="Metric Creation" /> <apex:form > <apex:pageBlock mode="edit"> <apex:pageMessages /> <apex:pageBlockButtons > <apex:commandButton action="{!save}" value="Save"/> <apex:commandButton action="{!cancel}" value="Cancel" immediate="true"/> </apex:pageBlockButtons> <apex:pageBlockSection title="Information" columns="2"> <apex:inputField value="{!metric.Name}" required="true"/> <apex:inputField value="{!metric.Description}" required="true"/> <apex:inputField value="{!metric.Rating}" /> <!-- etc --> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>

 

 

 

 

now output, note that the values i typed into the page are available inside the save() with no work required on my part, and the setter is not called.

 

 

***Begining Page Log for /apexpages/devmode/developerModeContainer.apexp 20090513185815.219:External entry point: returning SOBJECT:Account from method public SOBJECT:Account getMetric() in 0 ms 20090513185815.219:Class.MetricController.save: line 23, column 9: , same Id but within save(): Account:{Name=sdfdsf, Description=sdfdfs} 20090513185815.219:Class.MetricController.save: line 27, column 9: Insert: SOBJECT:Account 20090513185815.219:Class.MetricController.save: line 27, column 9: DML Operation executed in 43 ms 20090513185815.219:External entry point: returning NULL from method public System.PageReference save() in 45 ms Element j_id32 called method {!save} returned type PageReference: none20090513185815.219:External entry point: returning SOBJECT:Account from method public SOBJECT:Account getMetric() in 0 ms Cumulative profiling information: No profiling information for SOQL operations. No profiling information for SOSL operations. 1 most expensive DML operations: Class.MetricController.save: line 27, column 9: Insert: SOBJECT:Account: executed 1 time in 43 ms 2 most expensive method invocations: Class.MetricController: line 21, column 26: public System.PageReference save(): executed 1 time in 45 ms Class.MetricController: line 10, column 20: public SOBJECT:Account getMetric(): executed 2 times in 0 ms

 


 

 

This was selected as the best answer
eliotstockeliotstock
Thanks. I was confused about the lifecycle of the controller. Had thought nothing was happening to the SObject property on the controller but in fact stuff is being set on it.
d3developerd3developer

Is this a difference between inputField(s) and InputText as well?

 

Would the setter for an InputText field be called automatically?