Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

FacesConverter: value vs. forClass

Olá, estou com uma dúvida referente ao uso do converter usando ele com value ou forClass.

Quando eu uso o faces converter atribuindo um value pra ele e referenciando esse value no selectManyListbox, o valor é convertido e o cadastro é realizado com sucesso. Segue o código:

@FacesConverter("autorConverter")
public class AutorConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value == null || value.trim().isEmpty()) {
            return null;
        }

        final Autor autor = new Autor();
        autor.setId(Integer.valueOf(value));
        return autor;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        if (value == null) {
            return null;
        }
        final Autor autor = (Autor) value;
        return autor.getId().toString();
    }

}
<div>
    <h:outputLabel value="Autores" />
    <h:selectManyListbox id="autores" value="#{adminLivrosBean.livro.autores}"
        converter="autorConverter">
        <f:selectItems value="#{adminLivrosBean.autores}" var="autor"
            itemValue="#{autor}" itemLabel="#{autor.nome}" />
    </h:selectManyListbox>
    <h:message for="autores" />
</div>

Agora quando eu mudo o converter para forClass=Autor.class e tiro a referência do converter no selectManyListbox, ocorre erro de validação "j_idt2:autores: Erro de validação: o valor não é válido"

Segue o código com forClass:

@FacesConverter(forClass = Autor.class)
public class AutorConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value == null || value.trim().isEmpty()) {
            return null;
        }

        final Autor autor = new Autor();
        autor.setId(Integer.valueOf(value));
        return autor;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        if (value == null) {
            return null;
        }
        final Autor autor = (Autor) value;
        return autor.getId().toString();
    }

}
<div>
    <h:outputLabel value="Autores" />
    <h:selectManyListbox id="autores" value="#{adminLivrosBean.livro.autores}">
        <f:selectItems value="#{adminLivrosBean.autores}" var="autor"
            itemValue="#{autor}" itemLabel="#{autor.nome}" />
    </h:selectManyListbox>
    <h:message for="autores" />
</div>

O value do selectManyListBox é uma lista da classe Autor, não entendo porque ocorre erro de validação usando o forClass. É como se esse componente de selectManyListbox encapsulasse o value dele em algum outro objeto.

Depurando eu percebi que o método getAsString é chamado, enquanto que o getAsObject não foi chamado nenhum vez.

Alguém pode esclarecer melhor essa situação?

Obrigado.

1 resposta
solução!

Fala Diego, tudo bem?

Isso está acontecendo provavelmente porque na tentativa do forClass o converter converte Autor mas vc está querendo um Objeto do tipo List com o generics de Autor. Já na primeira vc define o conversor para aquela situação e o JSF se vira para fazer a conversão. Tente mudar o List para um Array de Autor no segundo caso, provavelmente ele funcionará.

Espero ter ajudado =)