I want to use the <f:validateWholeBean> Tag to validate multiple values in my BackingBean. I started with this example, but I got stuck somehow.
I added
<context-param>
<param-name>jakarta.faces.validator.ENABLE_VALIDATE_WHOLE_BEAN</param-name>
<param-value>true</param-value>
</context-param>
to my web.xml
.
In contrast to the example (which uses two textfields), I want to use the validation for the values of multiple h:selectOneMenu
-Fields in a h:dataTable
<h:form id="getPortPropsForm">
<h:dataTable value="#{ctl.portList}" var="port">
<h:column>
<f:facet name="header">#{msg['portName']}</f:facet>
<h:inputText id="name" value="#{port.name}" required="true" />
</h:column>
...
<h:column>
<f:facet name="header">#{msg['portMac']}</f:facet>
<h:selectOneMenu id="sel" value="#{port.macAddr}" required="true">
<f:selectItems value="#{ctl.list}" var="m" itemValue="#{m.mac}"/>
<f:validator validatorId="free_mac_validator"/>
<f:validateBean validationGroups="javax.validation.groups.Default ,my.UniqueMacValidationGroup"/>
</h:selectOneMenu>
</h:column>
</h:dataTable>
<h:commandButton id="submit" update="@form" value="save" action="#{ctl.persist()}">
<f:ajax execute="@form" render=":globalMessages"/>
</h:commandButton>
<f:validateWholeBean validationGroups="my.UniqueMacValidationGroup" value="#{ctl}"/>
</h:form>
My BackingBean
@ConversationScoped
@Named("ctl")
@UniqueMac(groups = UniqueMacValidationGroup.class)
public class AddSwitchController implements Serializable, MacHolder, Cloneable {
...
@NotNull(groups = UniqueMacValidationGroup.class)
@Override
public List<Mac> getMacAddresses() {
...
return macList;
}
...
@Override
public AddSwitchController clone() {
...
}
}
implements a methode which can be called by the validator
public class UniqueMacValidator implements ConstraintValidator<UniqueMac, MacHolder> {
...
@Override
public void initialize(UniqueMac constraintAnnotation) {
...
}
@Override
public boolean isValid(MacHolder macHolder, ConstraintValidatorContext constraintValidatorContext) {
List<Mac> macList = macHolder.getMacAddresses();
...
return false;
}
}
to get the values to check.
When I run the code, the free_mac_validator
is called for every instance of the h:selectOneMenu
and then I would expect my BackingBean to be cloned for the wholeBeanValidation, but the clone
Method is not called and I don't see how to proceed.
I'm not looking for a workaround, I want to understand, how this whole-bean-validation-mechanism works.