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]
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?