Faces4 -- f:validateWholeBean

51 Views Asked by At

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.

0

There are 0 best solutions below