[RESOLVIDO] Duvida com Converter

Olá pessoal…

Estou implementando um combo box de cidades, aonde estou com problema no converter.
Alguem pode me ajudarr ?? :shock:

Converter

package converter;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

import service.JPAUtil;

import model.Cidade;


@FacesConverter(value="cidadeConverter", forClass = Cidade.class)
public class CidadeConverter implements Converter{

	@Override
	public Object getAsObject(FacesContext arg0, UIComponent arg1, String value) {
		if(value != null && !value.isEmpty()){
			Long codigo = Long.valueOf(value);
			Cidade cid = JPAUtil.getEntityManager().find(Cidade.class,codigo);
			return cid;
	        }
	        return null;
	    }
	
	@Override
	public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
		if(arg2 != null){
			Cidade cid = (Cidade)arg2;
			if(cid.getCod_cidade() != null){
				return cid.getCod_cidade().toString();
			}
		}
		return null;        
	}

}

Bean Combo

[code]package managedBean;

import java.io.Serializable;
import java.util.List;

import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.persistence.EntityManager;

import model.Cidade;
import service.JPAUtil;

@ManagedBean(name=“cidadeComboMB”)
@ApplicationScoped
public class CidadeComboMB implements Serializable {

private static final long serialVersionUID = -8845930348740989024L;

@SuppressWarnings("unchecked")
public List<Cidade> getCidade(){
	EntityManager em = JPAUtil.getEntityManager();
	return em.createQuery("from Cidade cidade")
	.getResultList();
}

}
[/code]

página xhtml

<h:outputText value="Cidade:" /> 
					   	<h:form id="formCidade">
					  	    <h:selectOneMenu id="cbCidade" value="#{pacienteMB.paciente.cidade}" 
					   	    	converter="cidadeConverter" label="Cidade" required="false" >  
           							<f:selectItem itemLabel="SELECIONE"/>  
           							<f:selectItems value="#{cidadeComboMB.getCidade()}" var="cidade" 
           								itemLabel="#{cidade.nom_cidade}" itemValue="#{cidade}" />
							</h:selectOneMenu>	
							<h:commandButton id="btnCidade" value="..." />
						</h:form>

Mensagem obtida de erro é : Cidade: Erro de validação: o valor não é válido

Seu model implementa
equals e hashCode para id por exemplo?

Opa.

Sim, pacinteMB implementa o equals e o hashCode.

[quote=tiago.javaman]Opa.

Sim, pacinteMB implementa o equals e o hashCode.[/quote]
Digo no model não no managedbean. Cidade…

Sim, claro… Implementei tmb.

Segue.

[code]package model;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

@Entity
@Table(name=“Cidade”)
@NamedQuery(name=“Cidade”,query =“from Cidade”)
public class Cidade implements Serializable {

private static final long serialVersionUID = 8117232193595083558L;

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long cod_cidade;

@Column(length=100, nullable=false )
private String nom_cidade;

@Column(nullable=false)
private Date dat_cadastro;
private Date dat_alteracao;

@Column(nullable=false)
private Long cod_usuario_cadastro;
private Long cod_usuario_alteracao;


@ManyToOne
@JoinColumn(name="cod_estado", nullable=false)
private Estado estado;

public Long getCod_cidade() {
	return cod_cidade;
}

public void setCod_cidade(Long cod_cidade) {
	this.cod_cidade = cod_cidade;
}

public String getNom_cidade() {
	return nom_cidade;
}

public void setNom_cidade(String nom_cidade) {
	this.nom_cidade = nom_cidade;
}

public Date getDat_cadastro() {
	return dat_cadastro;
}

public void setDat_cadastro(Date dat_cadastro) {
	this.dat_cadastro = dat_cadastro;
}

public Date getDat_alteracao() {
	return dat_alteracao;
}

public void setDat_alteracao(Date dat_alteracao) {
	this.dat_alteracao = dat_alteracao;
}

public Long getCod_usuario_cadastro() {
	return cod_usuario_cadastro;
}

public void setCod_usuario_cadastro(Long cod_usuario_cadastro) {
	this.cod_usuario_cadastro = cod_usuario_cadastro;
}

public Long getCod_usuario_alteracao() {
	return cod_usuario_alteracao;
}

public void setCod_usuario_alteracao(Long cod_usuario_alteracao) {
	this.cod_usuario_alteracao = cod_usuario_alteracao;
}

public Estado getEstado() {
	return estado;
}

public void setEstado(Estado estado) {
	this.estado = estado;
}

@Override
public int hashCode() {
	final int prime = 31;
	int result = 1;
	result = prime * result
			+ ((cod_cidade == null) ? 0 : cod_cidade.hashCode());
	result = prime
			* result
			+ ((cod_usuario_alteracao == null) ? 0 : cod_usuario_alteracao
					.hashCode());
	result = prime
			* result
			+ ((cod_usuario_cadastro == null) ? 0 : cod_usuario_cadastro
					.hashCode());
	result = prime * result
			+ ((dat_alteracao == null) ? 0 : dat_alteracao.hashCode());
	result = prime * result
			+ ((dat_cadastro == null) ? 0 : dat_cadastro.hashCode());
	result = prime * result + ((estado == null) ? 0 : estado.hashCode());
	result = prime * result
			+ ((nom_cidade == null) ? 0 : nom_cidade.hashCode());
	return result;
}

@Override
public boolean equals(Object obj) {
	if (this == obj)
		return true;
	if (obj == null)
		return false;
	if (getClass() != obj.getClass())
		return false;
	Cidade other = (Cidade) obj;
	if (cod_cidade == null) {
		if (other.cod_cidade != null)
			return false;
	} else if (!cod_cidade.equals(other.cod_cidade))
		return false;
	if (cod_usuario_alteracao == null) {
		if (other.cod_usuario_alteracao != null)
			return false;
	} else if (!cod_usuario_alteracao.equals(other.cod_usuario_alteracao))
		return false;
	if (cod_usuario_cadastro == null) {
		if (other.cod_usuario_cadastro != null)
			return false;
	} else if (!cod_usuario_cadastro.equals(other.cod_usuario_cadastro))
		return false;
	if (dat_alteracao == null) {
		if (other.dat_alteracao != null)
			return false;
	} else if (!dat_alteracao.equals(other.dat_alteracao))
		return false;
	if (dat_cadastro == null) {
		if (other.dat_cadastro != null)
			return false;
	} else if (!dat_cadastro.equals(other.dat_cadastro))
		return false;
	if (estado == null) {
		if (other.estado != null)
			return false;
	} else if (!estado.equals(other.estado))
		return false;
	if (nom_cidade == null) {
		if (other.nom_cidade != null)
			return false;
	} else if (!nom_cidade.equals(other.nom_cidade))
		return false;
	return true;
}

}
[/code]

Ngm ? :shock:

O combo é montado direitinho, o problema é só na hora do submit certo?

Algumas dicas para ajudar na sua análise:

Veja o html gerado (View Source do browser), veja se ele gerou os options corretamente, com o label e value corretos (label é o nome da cidade, value provavelmente será convertido para o código)

Coloque um breakpoint no método getAsObject. Assim vc vai ver exatamente o que está chegando e que deu erro de conversão.

Gomes, tambem estou com um problema parecido, setei para o selectitem uma string e um int, que é o codigo da tabela no bd, mesmo assim preciso fazer essa conversão? Estou controlando os atributos no console, o bean recupera o “id”, mas na hora de seta-lo no objeto dá um erro “javax.faces.el.EvaluationException: java.lang.NullPointerException”. O que poderia ser feito?

Rapaziada!!

Resolvi meu problema…

Depois de uma noite perdida, em cima disso, pesquisando na net só me deparava com o povo falando do dito hashCode e .equals.
E como ja tinha postado aqui, minha classe model Cidade possuia os hashCode corretamente…

Lendo esse post do rafael ponte, http://www.rponte.com.br/2008/02/01/selectonemenu-converter-erro-de-validacao/, me liguei que minha classe Cidade
possui um relacionamento com Estado. E ai veio a surpresa. Funcionou tudo corretamente… Faltou o hashCode na Estado…

Fica a dica pro pessoal ai, agora sim eu percebi a extrema importancia de NUNCA esquecer de gerar o hashCode.

Obrigado a todos pela força. :oops:

Tiago, pelo que li no artigo, essa conversão só é preciso ser feita quando o valor do Selectitems não é a id. No meu caso setei a id na list, tanto que pelo console ela é exibida, uma linha antes de ser setada no objeto para ser salvo no bd. Ou tenho que fazer essa conversão mesmo assim?