Invalidar la edición de la tabla de datos de Primefaces en la edición de filas

Estoy desarrollando una aplicación web con JSF 2.1 + Primefaces 5.1. Tengo una tabla de datos con edición de fila y cada fila tiene 2inputText2selectOneMenu y 1selectBooleanCheckbox. Quiero realizar una validación de lógica de negocios al hacer clic en el icono de verificación: validará los valores de 2selectOneMenus. Para eso, creé un validador personalizado asociado con el segundoselectOneMenu que valida ambos valores:

<p:dataTable id="users_table_id" var="user" value="#{usersBean.users}" rowKey="#{user.id}" paginator="true"
            paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
               rowsPerPageTemplate="5,10,15" emptyMessage="#{msgs.no_records}" sortBy="#{user.id}" sortOrder="ascending" rows="15" editable="true">
            <f:facet name="header">
                #{msgs.users}               
            </f:facet>
            <p:ajax event="rowEdit" listener="#{usersBean.onRowEdit}" update=":users_form_id:growl"/>
            <p:ajax event="rowEditInit" listener="#{usersBean.onRowEditInit}" update=":users_form_id:growl"/>
            <p:ajax event="rowEditCancel" listener="#{usersBean.onRowEditCancel}" update=":users_form_id:growl"/>
            <p:column headerText="#{msgs.id}" sortBy="#{user.id}" styleClass="centered-column">
                #{user.id}
            </p:column>          
            <p:column headerText="#{msgs.description}" sortBy="#{user.description}" styleClass="centered-column">
                <p:cellEditor>
                    <f:facet name="output">#{user.description}</f:facet>
                    <f:facet name="input"><p:inputText value="#{user.description}" styleClass="editable-cell"/></f:facet>
                </p:cellEditor>
            </p:column>          
            <p:column headerText="#{msgs.password}" sortBy="#{user.password}" styleClass="centered-column">
                <p:cellEditor>
                    <f:facet name="output">#{user.password}</f:facet>
                    <f:facet name="input"><p:inputText value="#{user.password}" styleClass="editable-cell"/></f:facet>
                </p:cellEditor>
            </p:column>
            <p:column headerText="#{msgs.sending_system}" sortBy="#{user.playerIn.description}" styleClass="centered-column">
                <p:cellEditor>
                    <f:facet name="output">#{user.playerIn.description}</f:facet>
                    <f:facet name="input">
                        <p:selectOneMenu binding="#{userPlayerInComponent}" styleClass="editable-cell" id="users_table_sending_system_id" value="#{user.playerIn}" effectSpeed="fast" filter="true" filterMatchMode="contains" converter="#{playerConverter}">
                            <f:selectItem itemLabel="#{msgs.select_option}" itemValue="#{null}" noSelectionOption="true"/>
                            <f:selectItems value="#{usersBean.players}" var="player" itemValue="#{player}" itemLabel="#{player.description}"/>
                        </p:selectOneMenu>
                    </f:facet>
                </p:cellEditor>
            </p:column> 
            <p:column headerText="#{msgs.receiving_system}" sortBy="#{user.playerOut.description}" styleClass="centered-column">
                <p:cellEditor>
                    <f:facet name="output">#{user.playerOut.description}</f:facet>
                    <f:facet name="input">
                        <p:selectOneMenu styleClass="editable-cell" id="users_table_receiving_system_id" value="#{user.playerOut}" effectSpeed="fast" filter="true" filterMatchMode="contains" converter="#{playerConverter}">
                            <f:selectItem itemLabel="#{msgs.select_option}" itemValue="#{null}" noSelectionOption="true"/>
                            <f:selectItems value="#{usersBean.players}" var="player" itemValue="#{player}" itemLabel="#{player.description}"/>

                            <f:validator validatorId="userValidator"/>
                            <f:attribute name="userPlayerInComponent" value="#{userPlayerInComponent}"/>
                        </p:selectOneMenu>
                    </f:facet>
                </p:cellEditor>
            </p:column>                                     
            <p:column headerText="#{msgs.active}" sortBy="#{user.active}" styleClass="centered-column">
                <p:cellEditor>
                    <f:facet name="output"><p:selectBooleanCheckbox value="#{user.active}" disabled="true"/></f:facet>              
                    <f:facet name="input"><p:selectBooleanCheckbox value="#{user.active}"/></f:facet>
                </p:cellEditor>
            </p:column>
            <p:column styleClass="datatable-row-editor">
                <p:rowEditor/>
            </p:column>
            <f:facet name="footer">
            </f:facet>      
        </p:dataTable>
@FacesValidator("userValidator")
public class UserValidator implements Validator {

    private static final Logger logger =  LogManager.getLogger(UserValidator.class);

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        logger.entry(context, component, value);

        if (value == null) {
            return; // Let required="true" handle.
        }

        UIInput userPlayerInComponent = (UIInput)component.getAttributes().get("userPlayerInComponent");
        if (!userPlayerInComponent.isValid()) {
            return; // Already invalidated. Don't care about it then.
        }

        DtoPlayer playerIn = (DtoPlayer)userPlayerInComponent.getValue();
        if (playerIn == null) {
            return; // Let required="true" handle.
        }

        DtoPlayer playerOut = (DtoPlayer)value;

        UsersBean usersBean = context.getApplication().evaluateExpressionGet(context, "#{usersBean}", UsersBean.class);

        BigDecimal userId = usersBean.getUserEditingId();
        logger.info(userId + " - " + playerIn.getDescription() + " - " + playerOut.getDescription());

        for (DtoUser dtoUser : usersBean.getUsers()) {
            if (!userId.equals(dtoUser.getId()) && dtoUser.getPlayerIn().equals(playerIn) && dtoUser.getPlayerOut().equals(playerOut)) {
                logger.info("Invalidating...");
                userPlayerInComponent.setValid(false);              
                FacesContext.getCurrentInstance().validationFailed();
                throw new ValidatorException(new FacesMessage("BOOM!"));
            }
        }
        logger.exit();
    }
}

Estaba esperando eso, cuando falla la validación (y unValidatorException se lanza), la fila de la tabla de datos permanecería en modo de edición y los dosselectOneMenus resaltado con color rojo. Pero lo que sucede es que la fila sale del modo de edición, manteniendo los valores antiguos. Si lo vuelvo a editar, muestra los valores enviados y las celdas no válidas están marcadas en rojo. Y este comportamiento continúa mientras trato de enviar los valores no válidos. Si cierro el modo de edición, los valores no válidos se descartan y la fila mantiene solo los valores antiguos (ya sea en modo de vista o de edición).

¿Como puedo resolver esto? Desde elEscaparate de Primefaces, se puede ver que cuando intenta enviar, digamos, una cadena con caracteres alfabéticos en la celda del año, la fila mantiene el modo de edición y se resalta. Quiero lograr el mismo comportamiento.

Respuestas a la pregunta(0)

Su respuesta a la pregunta