You need to sign in to do that
Don't have an account?
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?
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
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
Is this a difference between inputField(s) and InputText as well?
Would the setter for an InputText field be called automatically?