I now see why I couldn't reproduce this yesterday. In my playground environment I had accidentally the following context param set differently from the default value:
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>
This problem is related to JSF issue 1492. A <f:validateDoubleRange>
whose attributes are by EL bound to a view scoped bean property will implicitly recreate the whole bean due to a nasty chicken-egg issue, because validators are created on a per-request basis and those properties are to be passed on validator's construction.
If you do not want to disable partial state saving (very reasonable), then your best bet is to create and hold the validator in the view scoped managed bean yourself:
public Validator getValidator() {
return new DoubleRangeValidator(foo.getMaximum(), foo.getMinimum());
}
(note, doing this stuff in a getter is a bad design, but since you're preparing foo
in a setter instead of a preRenderView
listener method, there's no other way, otherwise it would be done right in the same listener method)
with
<h:inputText validator="#{fooController.validator.validate}" ...>
Or, alternatively, to create a custom validator for that which replaces the <f:validateDoubleRange>
:
<f:validator validatorId="bindableDoubleRangeValidator" />
<f:attribute name="minimum" value="#{fooController.foo.minAmount}" />
<f:attribute name="maximum" value="#{fooController.foo.maxAmount}" />
with
package com.example;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.DoubleRangeValidator;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.ValidatorException;
@FacesValidator("bindableDoubleRangeValidator")
public class BindableDoubleRangeValidator extends DoubleRangeValidator {
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
setMinimum((Double) component.getAttributes().get("minimum"));
setMaximum((Double) component.getAttributes().get("maximum"));
super.validate(context, component, value);
}
}
Update: the chicken-egg issue 1492 is fixed since Mojarra 2.1.18 (January 2013). So if you stumble upon this these days, then you could also consider to just upgrade.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…