Combo jsf.... incluir f:selectItem - com itemLabel="---selecione---" [RESOLVIDO]

Boa noite pessoal.

Será que conseguem me ajudar?

Tenho um sistema em jsf e meus combos exibem apenas um list do que está cadastrado no banco de dados (oracle), isto funciona perfeitamente. O que ocorre, é que preciso incluir um itemLabel="—selecione—", cujo objeto do list seja nulo.

O que ocorre, é que inclui um <f:selectItem itemLabel=“selecione” itemValue="-1"/>, mas ao acessar a página, obtenho a mensagem de erro abaixo (caso seja necessário, posso postar toda mensagem de erro):

java.lang.ClassCastException: java.lang.String cannot be cast to sigaeweb.db.GrupoAlimento
	sigaeweb.Conversores.GrupoAlimentoConversor.getAsString(GrupoAlimentoConversor.java:39)
	com.icesoft.faces.renderkit.dom_html_basic.DomBasicRenderer.converterGetAsString(DomBasicRenderer.java:232)
	com.icesoft.faces.renderkit.dom_html_basic.DomBasicRenderer.formatComponentValue(DomBasicRenderer.java:198)

o código da minha pagina é:

...
    <ice:form>
        <ice:messages/>
        <div style="font-family: Arial, Helvetica, sans-serif; font-size: 11pt;" align="center">
            <ice:commandButton action="gotoAlimentoList" value="Voltar"/>
            <ice:commandButton action="#{AlimentoFace.finishAddAlimento}" value="Salvar"/><br/><br/>
            <ice:panelGrid columns="3">
                <ice:outputLabel value="grupo"/>
                <ice:selectOneMenu value="#{AlimentoFace.selectedAlimento.grupo}">
                    <f:selectItem itemLabel="selecione" itemValue="-1"/>
                    <f:selectItems value="#{AlimentoFace.listGrupo}"/>
                    <f:converter converterId="GrupoAlimentoConversor"/>
                    <f:validator validatorId="ComboValidador"/>
                </ice:selectOneMenu>
                <ice:outputText value=""/>
...

o código do meu bean é:

...
public class AlimentoFace {

    private AlimentoDAO aliDAO = new AlimentoDAO();
    private GrupoAlimentoDAO galiDAO = new GrupoAlimentoDAO();
    private SubGrupoalimentoDAO sgaliDAO = new SubGrupoalimentoDAO();
    private TipoAlimentoDAO taliDAO = new TipoAlimentoDAO();
    private TipoEmbalagemDAO embDAO = new TipoEmbalagemDAO();
    private Alimento selectedAlimento;
    private List<Alimento> alimento;
    private GrupoAlimento grupo;
    private SubGrupoalimento subGrupo;
    private String nomeAlimento;

    public AlimentoFace() {
        System.out.println("Alimento Face");
    }

    public String startAddAlimento () {
        selectedAlimento = new Alimento();
        return "gotoAddNewAlimento";
    }

    public String finishAddAlimento () throws ClassNotFoundException, SQLException {
        aliDAO.add(selectedAlimento);
        // Limpa o cache
        alimento = null;
        return "gotoAlimentoList";
    }
    public List<Alimento> getAlimento() throws ClassNotFoundException, SQLException {
        alimento = null;
        if (alimento == null){
            alimento = aliDAO.getAllAlimento();
        }
        return alimento;
    }

...

    public List<SelectItem> getListGrupo() throws ClassNotFoundException, SQLException {
        List<SelectItem> toReturn = new LinkedList<SelectItem>();
        for (GrupoAlimento gali: galiDAO.getAllGrupoAlimento()) {
            toReturn.add(new SelectItem(gali,gali.getGrupo()));
        }
        return toReturn;
    }

...

}

e o código do meu conversor do GrupoAlimento:

public class GrupoAlimentoConversor implements Converter {

    private static final long serialVersionUID = 1L;
    private GrupoAlimentoDAO galiDAO = new GrupoAlimentoDAO();

    public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
        Integer idGrupo = Integer.parseInt(arg2);
        try {
            return galiDAO.getById(idGrupo);
        } catch (SQLException ex) {
            Logger.getLogger(GrupoAlimentoConversor.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(GrupoAlimentoConversor.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
        GrupoAlimento gali = (GrupoAlimento)arg2;
        return String.valueOf(gali.getIdGrupo());
    }
}

como estava apresentando o erro, criei um validador, conforme abaixo:

public class ComboValidador implements javax.faces.validator.Validator {

    public void validate(FacesContext fc, UIComponent uic, Object o) {
        long parsedId;

        try {
            parsedId = Long.valueOf(o.toString());
        } catch (NumberFormatException nfe) {
            throw new ValidatorException(new FacesMessage("Error parsing Id."));
        }

        if(parsedId == -1) {
            o = null;
            return;
        }
    }
}

Mesmo com a criação do validador, o erro continua sendo apresentado.
Meu objetivo é apresentar a mensagem —Selecione— como default (objeto GrupoAlimento nulo), caso o valor do grupo alimento, do objeto alimento seja diferente de nulo, será apresentada a String referente a GrupoAlimento para o alimento em questão.

Tem alguma dica???

Vc não pode converter a string “-1” p/ GrupoAlimento. Tente usar null no lugar de -1.

Boa tarde Rafael.

Valeu pela dica, vou testar isto a noite e posto o resultado no fórum novamente.

Att:

José Luiz

.

.

.

Rafael, fiz o teste com “null”, e o erro persiste, testei também com “0”, “”, “{0}”, “{-1}”, “{null}” e “{}”. Nenhum dos casos funcionou. Seráque pode ser algo errado no meu conversor ou no validador?

Att:
José Luiz

.

Boa tarde pessoal…

Alguma idéia do que pode estar acontecendo???

Att:

José Luiz

vc esta tentando colocar um objeto do tipo GrupoAlimento no lugar de um id no selectItem
tente mudar de:

 public List<SelectItem> getListGrupo() throws ClassNotFoundException, SQLException {  
        List<SelectItem> toReturn = new LinkedList<SelectItem>();  
        for (GrupoAlimento gali: galiDAO.getAllGrupoAlimento()) {  
            toReturn.add(new SelectItem(gali,gali.getGrupo()));  
        }  
        return toReturn;  
    }   

para:

 public List<SelectItem> getListGrupo() throws ClassNotFoundException, SQLException {  
        List<SelectItem> toReturn = new LinkedList<SelectItem>();  
        for (GrupoAlimento gali: galiDAO.getAllGrupoAlimento()) {  
            toReturn.add(new SelectItem(gali.getId(),gali.getGrupo()));  //caso o objeto esteja seguindo o padrão javaBean
        }  
        return toReturn;  
    }  

Boa noite Wesley.

valeu pela dica, mas não funcionou. Ao realizar a alteração indicada, o problema de cast passa a ocorrer antes mesmo de eu chegar a pagina de insersão, já na minha página de filtro o problema ocorre.

Tem alguma outra dica para solucionar o problema?

Att:

José Luiz

Bom dia José Luiz,

tente fazer algo na sua jsp do tipo:

<h:selectOneMenu value="#{AlimentoFace.selectedAlimento.grupoId}"> //assumindo que grupoId seja um id de GrupoAlimento. Se não me engano String, caso contrário tente com Integer
      <f:selectItems value="#{AlimentoFace.listGrupo}"/>  
</h:selectOneMenu>

como percebeu, eu utilizo a tag:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>

e no seu beam AlimentoFace faça o seguinte:

 public List<SelectItem> getListGrupo() throws ClassNotFoundException, SQLException {  
        List<SelectItem> toReturn = new LinkedList<SelectItem>();
        toReturn.add(new SelectItem("0", "Selecione"));
        for (GrupoAlimento gali: galiDAO.getAllGrupoAlimento()) {
            toReturn.add(new SelectItem(gali.getId(), gali.getGrupo()));  
        }  
        return toReturn;  
    } 

att,

Wesley, valeu pelas dicas. Ajudou muito!!!

Consegui fazer funcionar com sua ultima dica… meu list do bean ficou assim:

    public List<SelectItem> getListGrupo() throws ClassNotFoundException, SQLException {
        List<SelectItem> toReturn = new LinkedList<SelectItem>();
        toReturn.add(new SelectItem(null, "--selecione--"));
        for (GrupoAlimento gali: galiDAO.getAllGrupoAlimento()) {
            toReturn.add(new SelectItem(gali,gali.getGrupo()));
        }
        return toReturn;
    }

Para funcionar, tive que alterar meu conversor, ficou assim:

public class GrupoAlimentoConversor implements Converter {

    private static final long serialVersionUID = 1L;
    private GrupoAlimentoDAO galiDAO = new GrupoAlimentoDAO();

    public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
        Integer idGrupo = Integer.parseInt(arg2);
        try {
            if (idGrupo == null) {
                return null;
            }
            return galiDAO.getById(idGrupo);
        } catch (SQLException ex) {
            Logger.getLogger(GrupoAlimentoConversor.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(GrupoAlimentoConversor.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
        if (arg2 == null) {
            return null;
        }
        GrupoAlimento gali = (GrupoAlimento)arg2;
        return String.valueOf(gali.getIdGrupo());
        /*return (arg2==null ? null : arg2.toString());*/
        /*return (arg2==null ? null : String.valueOf(gali.getIdGrupo()));*/

    }
}

E minha pagina ficou assim:

                <ice:selectOneMenu value="#{AlimentoFace.selectedAlimento.grupo}">
                    <f:selectItems value="#{AlimentoFace.listGrupo}"/>
                    <f:converter converterId="GrupoAlimentoConversor"/>
                </ice:selectOneMenu>

Obrigado a todos que contribuiram com o post. Valeu!!!

José Luiz