Problema com JSF : Custon Converter

2 respostas
Jeferson_Manetti

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:
[url]http://www.rponte.com.br/2008/02/01/selectonemenu-converter-erro-de-validacao/[/url]

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
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<Acesso> 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;
	}
	
}
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

2 Respostas

Jeferson_Manetti

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...
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");
        } 
  
	}

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

Jeferson_Manetti

alguem?

:cry:

help me!!!

Criado 25 de maio de 2009
Ultima resposta 26 de mai. de 2009
Respostas 2
Participantes 1