I have an h:selectOneRadio component that I have mapped to a Boolean (not boolean) in the backing bean. On load, the radio buttons do not have a default select option, and the radio button is not a required field.
Example code:
JSF page excerpt:
<h:form>
<h:selectOneRadio value="#{pagecode.test}">
<f:selectItem itemValue="#{true}" itemLabel="Yes"/>
<f:selectItem itemValue="#{false}" itemLabel="No"/>
</h:selectOneRadio>
<h:commandButton value="Save" action="#{pagecode.save}"/>
</h:form>
Backing Java pagecode:
package pagecode;
public class JSFBooleanTestView extends PageCodeBase {
protected Boolean test;
public Boolean getTest() {
return test;
}
public void setTest(Boolean test) {
this.test = test;
}
public String save() {
return "JSFBooleanTestView";
}
}
faces-config.xml excerpt:
<managed-bean>
<managed-bean-name>pagecode</managed-bean-name>
<managed-bean-class>pagecode.JSFBooleanTestView</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
Since test is not being defaulted to a value, the radio buttons start off unselected. Since the field is not required, my expectation was that pressing the Save button with no radio button selected would lead to test being null. Instead, test is assigned false.
Different options that I have tried that have had no effect:
Setting
h:selectOneRadio required="false"Adding to web.xml:
<context-param> <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name> <param-value>true</param-value> </context-param>Adding to web.xml:
<context-param> <param-name>org.apache.el.parser.COERCE_TO_ZERO</param-name> <param-value>false</param-value> </context-param>
What did work was adding immediate="true" to h:commandButton.
My questions:
What is making
h:selectOneRadioconvert nulls to false normally? Is that the intended behavior?Why does
immediate="true"makeh:commandButtonnot convert the nulls to false? What exactly isimmediate="true"doing differently in this particular situation that is causing the difference? I understand that theimmediate="true"will skip certain phases in the JSF lifecycle, but I don't understand what in those phases is causing the conversion from null to false to occur.
Edit:
I just realized I added immediate="true" to the h:commandButton, not the h:selectOneRadio. My question has been edited accordingly.
This is used in a portlet application on IBM WebSphere Portal 8.0 using Apache MyFaces 2.0.
COERCE_TO_ZEROis not a context param. It's a VM argument (and server-dependent). Set it as VM argument, retry and then we can talk further. In any case, always include detail about JSF impl/version and server impl/version, otherwise anyone reading this question will assume latest versions of their favourite JSF and server impl. - BalusCBooleanis interpreted asboolean,Integeris interpreted asint,Characteris interpreted aschar, etc and their default values will become the default value of the wrapped primitive (false,0,\u0000, etc) instead ofnull. And, sorry it's application wide. So if code was incorrectly relying on empty strings being the correct behavior, things may fail (although that would usually only expose hidden bugs which finally get chance to be really fixed, so you'd actually be happy instead ;) ). - BalusC