JSF - SelectOneMenu - Erro de validação: o valor não é válido (Primefaces)

8 respostas
F

Bom dia pessoal!

Estou com problema em um SelectOneMenu,
creio eu, que o que eu fiz pra exibir o SelectOneMenu é um pouco de gambiarra, mas foi a unica solução em que pensei, e achei que funcionaria...

O que eu pensei foi o seguinte, como eu tenho dois List que são do mesmo tipo, se eu colocar eles em um SelectOneMenu, e na hora da validação colocar ele em um atributo do mesmo tipo, iria funcionar... Mas não foi o que aconteceu...

Erro no SelectOneMenu: wizPanel:tabPreNegociacao: Erro de validação: o valor não é válido

Veja meus códigos: xhtml:
<p:selectOneMenu id="tabPreNegociacao" value="#{pedidoBean.tabPreNegociacao}" converter="converterTabela">
                                                <f:selectItems value="#{pedidoBean.tabelasNegociacaoEst}" var="t" itemValue="#{t}" itemLabel="Estado: #{t.est_id.est_nome}"/>
                                                <f:selectItems value="#{pedidoBean.tabelasNegociacaoCli}" var="t" itemValue="#{t}" itemLabel="Cliente: #{t.cli_id.cli_razao}"/>
                                            </p:selectOneMenu><p:messages/>
atributos:
private Tabela tabPreNegociacao;
    private List<Tabela> tabelasNegociacaoCli;
    private List<Tabela> tabelasNegociacaoEst;
Converter:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.zanzini.converter;

import br.com.zanzini.dao.TabelaDao;
import br.com.zanzini.entity.Tabela;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

/**
 *
 * @author altitdb
 */
@FacesConverter(value = "converterTabela")
public class ConverterTabela implements Converter {
    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value != null && !value.equals("")) {
            TabelaDao tabDao = new TabelaDao();
            return tabDao.getTabelaById(Long.valueOf(value));
        }
        return null;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        if (value instanceof Tabela) {
            Tabela tabela = (Tabela) value;
            return String.valueOf(tabela.getTab_id());
        }
        return "";
    }
}

Alguém consegue enxergar o por quê de não funcionar corretamente?

Obrigado desde já!

8 Respostas

getAdicted

Bom dia amigo,

Eu não sei se dessa forma funcionará, uma solução seria você popular uma lista a partir das suas duas outras listas:

private List&lt;Tabela&gt; tabelasNegociacaoCli; private List&lt;Tabela&gt; tabelasNegociacaoEst;
O combo fica certinho, com a informação das duas listas?

[]'s

Rodrigo_Sasaki

E por acaso Tabela tem o método equals sobrescrito corretamente?

getAdicted

Você não precisa colocar o nome completamente qualificado da classe tanto na classe de conversão quanto na página JSF?

@FacesConverter(value = "br.com.zanzini.converter.converterTabela") converter="br.com.zanzini.converter.converterTabela"
[]'s

F

getAdicted:
Bom dia amigo,

Eu não sei se dessa forma funcionará, uma solução seria você popular uma lista a partir das suas duas outras listas:

private List&lt;Tabela&gt; tabelasNegociacaoCli; private List&lt;Tabela&gt; tabelasNegociacaoEst;
O combo fica certinho, com a informação das duas listas?

[]'s


Sim, as informações ficam todas corretas, e no codigo HTML os ID do objeto também estão corretos…

Não tenho nenhum .equals em nenhum lugar… Como eu colocaria isso corretamente?

getAdicted:
Você não precisa colocar o nome completamente qualificado da classe tanto na classe de conversão quanto na página JSF?

@FacesConverter(value = "br.com.zanzini.converter.converterTabela") converter="br.com.zanzini.converter.converterTabela"
[]'s


Dessa sua forma o converter funciona da mesma forma…

Rodrigo_Sasaki
faelzindc:
Rodrigo Sasaki:
E por acaso Tabela tem o método equals sobrescrito corretamente?
Não tenho nenhum .equals em nenhum lugar... Como eu colocaria isso corretamente?
É, isso é um erro comum.

Esse erro pega muita gente, a especificação do JSF diz que o resultado retornado pelo converter, tem que ser igual a um dos itens da lista que é disponível para o usuário selecionar.

Como ele verifica o resultado retornado com os itens da lista? com o método equals.

Se ele não encontrar nenhum objeto que retorne true em um teste equals, ele diz que o valor é inválido.

Você precisa sobrescrever o método equals (que você herda de Object), fazendo com que ele diga se um objeto é igual a outro, baseado no critério que fizer sentido na sua aplicação.

Por exemplo, eu tenho um objeto Pessoa, e pra mim 2 pessoas iguais são aquelas que tem o nome igual, então sobrescrevo o método seguindo essa lógica.
public class Pessoa{

    private String nome;

    public void setNome(String nome){
        this.nome = nome;
    }

    public String getNome(){
        return nome;
    }

	@Override
	public boolean equals(Object obj){
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Pessoa))
			return false;
		Pessoa other = (Pessoa) obj;
		if (nome == null){
			if (other.nome != null)
				return false;
		} else if (!nome.equals(other.nome))
			return false;
		return true;
	}

}
Obs: Esse método equals foi gerado automaticamente pra mim pelo Eclipse.
F
Rodrigo Sasaki:
faelzindc:
Rodrigo Sasaki:
E por acaso Tabela tem o método equals sobrescrito corretamente?
Não tenho nenhum .equals em nenhum lugar... Como eu colocaria isso corretamente?
É, isso é um erro comum.

Esse erro pega muita gente, a especificação do JSF diz que o resultado retornado pelo converter, tem que ser igual a um dos itens da lista que é disponível para o usuário selecionar.

Como ele verifica o resultado retornado com os itens da lista? com o método equals.

Se ele não encontrar nenhum objeto que retorne true em um teste equals, ele diz que o valor é inválido.

Você precisa sobrescrever o método equals (que você herda de Object), fazendo com que ele diga se um objeto é igual a outro, baseado no critério que fizer sentido na sua aplicação.

Por exemplo, eu tenho um objeto Pessoa, e pra mim 2 pessoas iguais são aquelas que tem o nome igual, então sobrescrevo o método seguindo essa lógica.
public class Pessoa{

    private String nome;

    public void setNome(String nome){
        this.nome = nome;
    }

    public String getNome(){
        return nome;
    }

	@Override
	public boolean equals(Object obj){
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Pessoa))
			return false;
		Pessoa other = (Pessoa) obj;
		if (nome == null){
			if (other.nome != null)
				return false;
		} else if (!nome.equals(other.nome))
			return false;
		return true;
	}

}
Obs: Esse método equals foi gerado automaticamente pra mim pelo Eclipse.

Perfeito!
Era isso mesmo...
Esse erro não cometerei mais ;P hhuauha

Obrigado!
Abraço!

A

Parabéns Rodrigo Sasaki !
Excelente explicação e solução!

Nada como uma explicação bem embasada para resolver um problema de deixar todo mundo maluco!

diogojpb

O post parece ser antigo, mas preciso dar os parabéns ao Rodrigo Sasaki.
Foi claro e, pelo menos no meu caso, a dica solucionou o problema.

Abs

Criado 19 de dezembro de 2012
Ultima resposta 18 de jun. de 2014
Respostas 8
Participantes 5