Problema com JSF : Custon Converter

ola,

estou com um problema classico: Validation Error: Value is not valid Converter

antes de mais nada ja pesquisei no forum e na net…

ate encontrei bons artigos tipo este:
http://www.rponte.com.br/2008/02/01/selectonemenu-converter-erro-de-validacao/

tenho as classe Perfilusuario e Usuario, onde um Usuario possui um perfil e um perfil possui varios usuarios ( 1…*)
no meu cadastro de usuario tenho um selectOneMenu no qual esta listados meus Perfis.
ate aqui td otimo.

em ambas classes implementei os metodos equals e hashcode (ambos utilizando o id) e toString (onde consta o id e o nome).

tenho um converter “PerfilusuarioConverter” no qual ira converter o item selecionado no SelectOneMenu e um Perfil… td tranquilo…

pelo q pesquisei na net ele compara o item retornado pelo converter com aqueles passados na lista…

tenho os seguintes linhas no banco.

ID | Nome |

1 | Administrador |
2 | Convidado |

faço um busca no banco com hibernate e ele monta um List contendo os perfis da tabela acima… e coloco isso
em um SelectItem para apararecer no Combo… td tranquilo…

em meu converter ele busca no banco e retorna o Perfil correto… tambem tranquilo…

mas na hora q vou Salvar o bendito da erro… de validação…
percebi q no metodo equals do Perfilusuario ele esta retornando False pq esta como Null… totalmente estranho…

segue uma execução aqui escolhi o perfil Administradores no Combo:

11:13:08,204  INFO appLogger:27 - lendo class br.com.corpus.model.entity.PerfilUsuario com id 1.
Perfil Converter >>> 1 - Administradores
11:13:09,980  INFO appLogger:85 - Query: from PerfilUsuario perfil Paramentros: 
Comparando os IDs : false
Id do objeto : 1
Id comparado : null
Comparando os IDs : false
Id do objeto : 1
Id comparado : 2

11:13:10,042  INFO appLogger:85 - Query: from PerfilUsuario perfil Paramentros: 
Perfil Converter to String >>> 1 - Administradores
Perfil Converter to String >>> 2 - Convidado

segue outra execução aqui escolhi o perfil Convidado no Combo:

11:38:07,434  INFO appLogger:27 - lendo class br.com.corpus.model.entity.PerfilUsuario com id 2.
Perfil Converter >>> 2 - Convidado
11:38:07,434  INFO appLogger:85 - Query: from PerfilUsuario perfil Paramentros: 
Comparando os IDs : false
Id do objeto : 2
Id comparado : 1
Comparando os IDs : false
Id do objeto : 2
Id comparado : null

11:38:07,481  INFO appLogger:85 - Query: from PerfilUsuario perfil Paramentros: 
Perfil Converter to String >>> 1 - Administradores
Perfil Converter to String >>> 2 - Convidado

pq ele esta aparecendo Null no perfil escolhido…
bom segue minhas classes…

PerfilUsuario

[code]
package br.com.corpus.model.entity;

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

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;

@Entity
public class PerfilUsuario implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;

@Column(nullable=false)
private String nome;

// @ManyToMany(mappedBy=“perfisUsuario”, cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@ManyToMany(cascade={CascadeType.MERGE,CascadeType.PERSIST} , fetch=FetchType.LAZY)
@JoinTable(name=“Perfil_Acesso”,
joinColumns= @JoinColumn(name=“perfil_id”, referencedColumnName=“id”),
inverseJoinColumns= @JoinColumn(name=“acesso_id”, referencedColumnName=“id”))
private List acessos;

@OneToMany(cascade=CascadeType.ALL,	mappedBy="perfil", fetch=FetchType.LAZY)
private List<Usuario> usuarios;

/***************** Method ******************/

public PerfilUsuario() {
	this.acessos = new ArrayList<Acesso>();
	this.usuarios = new ArrayList<Usuario>();
}

public void addUsuario(Usuario usuario){
	this.usuarios.add(usuario);
	usuario.setPerfil(this);
}

public void addAcesso(Acesso acesso){
	this.acessos.add(acesso);
	acesso.getPerfisUsuario().add(this);
}


/********** Getter and Setter *************/

public Integer getId() {
	return id;
}

public void setId(Integer id) {
	this.id = id;
}

public String getNome() {
	return nome;
}

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

public List<Acesso> getAcessos() {
	return acessos;
}

public void setAcessos(List<Acesso> acessos) {
	this.acessos = acessos;
}

public List<Usuario> getUsuarios() {
	return usuarios;
}

public void setUsuarios(List<Usuario> usuarios) {
	this.usuarios = usuarios;
}

/************ equals and hashCode ********************/

@Override
public int hashCode() {
	final int prime = 31;
	int result = 1;
	result = prime * result + ((id == null) ? 0 : id.hashCode());
	return result;
}

@Override
public boolean equals(Object obj) {
	if (this == obj)
		return true;
	if (obj == null)
		return false;
	if (!(obj instanceof PerfilUsuario))
		return false;
	PerfilUsuario other = (PerfilUsuario) obj;
	if (id == null) {
		if (other.id != null)
			return false;
	} else if (!id.equals(other.id)){
		System.out.println("Comparando os IDs : " + id.equals(other.id));
		System.out.println("Id do objeto : " + id);
		System.out.println("Id comparado : "+ other.id);
		return false;
	}
	return true;
} 

@Override
public String toString() {
	return id + " - " + nome;
}

}[/code]

PerfilUsuarioConverter

package br.com.corpus.controller.converter;

import java.util.StringTokenizer;

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

import br.com.corpus.model.entity.PerfilUsuario;
import br.com.corpus.model.service.PerfilUsuarioService;

public class PerfilUsuarioConverter implements Converter {

	@Override
	public Object getAsObject(FacesContext context, UIComponent component, String str) {
		try {
			
			if (str == null) {
	            return null;
	        }

			Integer id = Integer.valueOf(new StringTokenizer(str).nextToken());

			PerfilUsuario perfil = PerfilUsuarioService.getPerfil(id);
			System.out.println("Perfil Converter >>> " + perfil);
			return perfil;
		
		} catch (Exception e) {
			e.printStackTrace();
			
			return null;
		}

		
	}

	@Override
	public String getAsString(FacesContext context, UIComponent component, Object obj) {

		if (obj == null) {
            return null;
        }	

		if(obj instanceof PerfilUsuario) {
			
			PerfilUsuario perfil = (PerfilUsuario) obj;
			
			System.out.println("Perfil Converter to String >>> " + perfil.toString());
            return perfil.toString();
            
        } else {        	
            throw new IllegalArgumentException("object:" + obj+ 
            		"of type:" + obj.getClass().getName() + "; expected type:"+
            			"br.com.corpus.model.entity.PerfilUsuario");
        } 
  
	}

}

UsuarioHandler

package br.com.corpus.controller.managedBeans;

import java.util.ArrayList;
import java.util.List;

import javax.faces.component.html.HtmlSelectOneMenu;
import javax.faces.model.SelectItem;

import br.com.corpus.model.entity.PerfilUsuario;
import br.com.corpus.model.entity.Usuario;
import br.com.corpus.model.service.PerfilUsuarioService;
import br.com.corpus.model.service.UsuarioService;

public class UsuarioHandler {
	
	private Usuario usuario;
	
	private List<Usuario> listaUsuarios;
	
	private HtmlSelectOneMenu perfilSelecionado;

	 
	/******************* Method ****************/
	public UsuarioHandler() {
		usuario = new Usuario();
	}
	
	public String novousuario(){
		usuario = new Usuario();
		return "cad-usuario";
	}
		
	public String salvar() throws Exception{
							
		new UsuarioService().salvarUsuario(usuario);
				
		usuario = new Usuario(); 
		
//		listaUsuarios = null;
		
		return "lista-usuario";
	}
	
	public String deletar() throws Exception{
		
		new UsuarioService().deletarUsuario(usuario);
		
//		listaUsuarios = null;
		
		return "lista-usuario";
	}
	
	public List<SelectItem> getPerfisComboBox()throws Exception{

		List<PerfilUsuario> listaPerfil = PerfilUsuarioService.getListPerfil();
		List<SelectItem> lista = new ArrayList<SelectItem>();
		
		for (PerfilUsuario perfil : listaPerfil) {
			lista.add(new SelectItem(perfil, perfil.getNome()));
		}
				
		return lista;
	}
	

	
	/******** getter and setter ************/
	
	public Usuario getUsuario() {
		return usuario;
	}

	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}

	public HtmlSelectOneMenu getPerfilSelecionado() {
		return perfilSelecionado;
	}

	public void setPerfilSelecionado(HtmlSelectOneMenu perfilSelecionado) {
		this.perfilSelecionado = perfilSelecionado;
	}

	public List<Usuario> getListaUsuarios() throws Exception {		
//		if(listaUsuarios == null)
			listaUsuarios = new UsuarioService().getListUsuario();
		
		return listaUsuarios;
	}

	
	
}

e finalmente Cad-Usuario.jsp

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich" %>
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<link rel="shortcut icon" href="../../favicon.ico"/>
	<link rel="stylesheet" href="../../recursos/css/cadastro_css.css" type="text/css" /> 
	<link rel="icon" type="image/gif" href="../../animated_favicon1.gif"/>
	<link rel="stylesheet" href="../../recursos/css/sistema_css.css" type="text/css" />
	<link rel="stylesheet" href="../../recursos/css/rounded_corners.css" type="text/css" /> 
	<script type="text/javascript" src="../../recursos/js/niftyLayout.js"></script>
	<script type="text/javascript" src="../../recursos/js/niftycube.js"></script> 
	<title>Cadastro Usuário</title>
</head> 

<body>
	<f:view>
		<div id="wrap">
			<jsp:include page="/include/header.jsp" />
			<div id="menu">
				<a4j:include viewId="/include/menu.jsp" />
			</div>
		    <div id="mainBody">	
		    
		<fieldset><legend>Cadastro Usuário</legend>
					
					<h:form id="cadastro" styleClass="cadForm">
					
						<h:panelGrid columns="3">
							
							<h:outputText value="Nome:" styleClass="label"/>
							<h:inputText label="Nome" id="nome" required="true" value="#{usuarioHandler.usuario.nome}" >
								<rich:ajaxValidator event="onblur"/>
							</h:inputText>
							<rich:message for="nome">
                        		<f:facet name="passedMarker">
                            		<h:graphicImage  value="/recursos/imagens/passed.gif" /> 
                        		</f:facet>
                        		<f:facet name="errorMarker">
                            		<h:graphicImage value="/recursos/imagens/error.gif" />   
                        		</f:facet>
                    		</rich:message>
							
																	
							<h:outputText value="Login:" styleClass="label"/>
							<h:inputText label="Login" id="login" required="true" value="#{usuarioHandler.usuario.login}" >
								<rich:ajaxValidator event="onblur"/>
							</h:inputText>
							<rich:message for="login">
                        		<f:facet name="passedMarker">
                            		<h:graphicImage  value="/recursos/imagens/passed.gif" /> 
                        		</f:facet>
                        		<f:facet name="errorMarker">
                            		<h:graphicImage value="/recursos/imagens/error.gif" />   
                        		</f:facet>
                    		</rich:message>
							
							<h:outputText value="Senha:" styleClass="label"/>
							<h:inputSecret label="Senha" id="password" required="true" value="#{usuarioHandler.usuario.senha}" >
								<rich:ajaxValidator event="onblur"/>
							</h:inputSecret>
							<rich:message for="password">
                        		<f:facet name="passedMarker">
                            		<h:graphicImage  value="/recursos/imagens/passed.gif" /> 
                        		</f:facet>
                        		<f:facet name="errorMarker">
                            		<h:graphicImage value="/recursos/imagens/error.gif" />   
                        		</f:facet>
                    		</rich:message>
							
							<h:outputText value="E-mail:" styleClass="label"/>
							<h:inputText label="E-mail" id="email" value="#{usuarioHandler.usuario.email}" >
								<rich:ajaxValidator event="onblur"/>
							</h:inputText>
							<rich:message for="email">
                        		<f:facet name="passedMarker">
                            		<h:graphicImage  value="/recursos/imagens/passed.gif" /> 
                        		</f:facet>
                        		<f:facet name="errorMarker">
                            		<h:graphicImage value="/recursos/imagens/error.gif" />   
                        		</f:facet>
                    		</rich:message>
							
							<h:outputText value="Perfil:" styleClass="label"/>
							<h:selectOneMenu label="Perfil" id="perfil" value="#{usuarioHandler.usuario.perfil}" >
								<f:selectItems value="#{usuarioHandler.perfisComboBox}"/>
								<f:converter converterId="PerfilUsuarioConverter"/>
							</h:selectOneMenu>
							<rich:message for="perfil">
                        		<f:facet name="passedMarker">
                            		<h:graphicImage  value="/recursos/imagens/passed.gif" /> 
                        		</f:facet>
                        		<f:facet name="errorMarker">
                            		<h:graphicImage value="/recursos/imagens/error.gif" />   
                        		</f:facet>
                    		</rich:message>
							
							<h:outputText value="Descrição:" styleClass="label"/>
							<h:inputTextarea label="Descrição" id="descricao" value="#{usuarioHandler.usuario.descricao}" />
							<rich:message for="descricao">
                        		<f:facet name="passedMarker">
                            		<h:graphicImage  value="/recursos/imagens/passed.gif" /> 
                        		</f:facet>
                        		<f:facet name="errorMarker">
                            		<h:graphicImage value="/recursos/imagens/error.gif" />   
                        		</f:facet>
                    		</rich:message>
                    									
						</h:panelGrid>
						
						<br />
						<h:panelGrid columns="2" styleClass="ButtonBox">
							<h:commandButton action="#{usuarioHandler.salvar}" value="Salvar" />
							<h:commandButton action="lista-usuario" immediate="true" value="Voltar" />
						</h:panelGrid>
	
					</h:form>
			
		</fieldset>
        
		  	</div>
		<jsp:include page="/include/footer.jsp" />
		</div>
	</f:view>
</body>
</html>

alguem poderia me ajudar… não estou conseguindo achar uma solução…

ficaria muito feliz =)

desde ja agradeço… at.

jeferson

ola novamente,

consegui resolver o problema…

alterei meu converter… agora alem de ele buscar o objeto no banco pelo Id eu busco pelo Nome…

ele funciona normalmente…

seria conhecidencia o campo nome ser o mesmo campo q eu passa na descrição do SelectItem?

deem uma olhada…

[code]
package br.com.corpus.controller.converter;

import java.util.StringTokenizer;

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

import br.com.corpus.model.entity.PerfilUsuario;
import br.com.corpus.model.service.PerfilUsuarioService;

public class PerfilUsuarioConverter implements Converter {

@Override
public Object getAsObject(FacesContext context, UIComponent component, String str) {
	try {
		
		if (str == null) {
            return null;
        }

		PerfilUsuario perfil = PerfilUsuarioService.getPerfilByNome(str);
		
		System.out.println("Perfil Converter >>> " + perfil);
		return perfil;
	
	} catch (Exception e) {
		e.printStackTrace();
		
		return null;
	}

	
}

@Override
public String getAsString(FacesContext context, UIComponent component, Object obj) {

	if (obj == null) {
        return null;
    }	

	if(obj instanceof PerfilUsuario) {
		
		PerfilUsuario perfil = (PerfilUsuario) obj;
		
		System.out.println("Perfil Converter to String >>> " + perfil.toString());
        return perfil.getNome();
        
    } else {        	
        throw new IllegalArgumentException("object:" + obj+ 
        		"of type:" + obj.getClass().getName() + "; expected type:"+
        			"br.com.corpus.model.entity.PerfilUsuario");
    } 

}

}[/code]

Lista para o Combo

public List<SelectItem> getPerfisComboBox()throws Exception{

		List<PerfilUsuario> listaPerfil = PerfilUsuarioService.getListPerfil();
		List<SelectItem> lista = new ArrayList<SelectItem>();
		
		for (PerfilUsuario perfil : listaPerfil) {
			lista.add(new SelectItem(perfil, perfil.getNome()));
		}
				
		return lista;
	}

fico desconfiado ¬¬

alguem poderia me falar se isto tem alguma relação?

bom… ate resolvi meu problema mais criei outro…
sendo o campo nome uma campo texto normal… e não uma chave no banco…

o cidadão poderia colocar 2 nomes iguais dai… problema na hora da busca…

ainda gostaria que fosse pelo Id…

sera q alguma alma bondosa pderia me ajudar?

alguem?

:cry:

help me!!!