[RESOLVIDO]Duvida com <h:selectOneMenu>

raf4ever

continua dando o mesmo erro
tudo isto por causa de um maldito converter

Oi Geeh_All,

Sua classe Converter está sendo chamada? Qual valor chega no método getAsObject()? Se não passar por ele, olha se chama o getAsString(), e olha qual valor chega. Feito isso, olhe se o find do DAO está retornando o esperado.

Outra coisa, olhe o html gerado. Repare se o componente está com id setado, e se cada está com o value definido corretamente.

Se nada disso funcionar, faz sem o primefaces, para saber se é alguma coisa nele que está atrapalhando.

Uma boa sugestão quando você está parado em um erro é fazer tentativas por etapas. Tire componentes e veja o que funciona e o que continua com erro. Repita isso até funcionar normal, depois vai acrescentando um a um até encontrar o problema. Eu sei que isso é trabalhoso, mas… bem vindo ao mundo da programação 8)

Alys,

so confere para ver se meu converter esta do modo certo


package implementacoes;

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

import dao.MarcaDao;
import entidade.Marca;

@FacesConverter(value="converterMarca")
public class ConverterMarca implements Converter {

	@Override
	public Object getAsObject(FacesContext context, UIComponent component, String value) {
		if (value != null && !value.equals("")) {
		MarcaDao dao = new MarcaDao();
		return dao.find(Long.valueOf(value));
		}
		return null;
	}

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

}

Cara,

Os métodos e as anotações estão certas. Deve estar vindo algo errado da tela. Olha só, montei um exemplo básico aqui, a partir do seu, e estou recuperando o valor sem problemas no ManagedBean.

Converter:

@FacesConverter(value="converterMarca")  
public class ConverterMarca implements Converter {  
  
    @Override  
    public Object getAsObject(FacesContext context, UIComponent component, String value) {  
        if (value != null && !value.equals("")) {
        	Marca marca = new Marca(123, "Setado no Converter");
	        return marca;  
        }  
        return null;  
    }  
  
    @Override  
    public String getAsString(FacesContext context, UIComponent component, Object value) {  
        if (value instanceof Marca) {  
	        Marca marca = (Marca) value;  
	        return String.valueOf(marca.getId());  
        }  
        return "";  
    }  
  
} 

Página:

    <h:form id="cadastro">  
        <h:panelGrid id="cadastroProduto" columns="2" >  
            <h:outputLabel for="marca" value="Marca" />    
                 <h:selectOneMenu id="marca" value="#{listaBean.marcaSelecionada}">    
                      <f:selectItems value="#{listaBean.marcas}" />
                      <f:converter converterId="converterMarca"/>
                </h:selectOneMenu>    
                <h:commandButton actionListener="#{listaBean.saveObject()}" value="Cadastrar"/>  
        </h:panelGrid>  
    </h:form> 

Managed Bean:

@ManagedBean(name = "listaBean")  
@RequestScoped  
public class ListaExemploBean {
private Marca marcaSelecionada;
	
	public List<Marca> getMarcas(){
		List<Marca> marcas = new ArrayList<Marca>();
		
		marcas.add(new Marca(123, "Teste 1"));
		marcas.add(new Marca(124, "Teste 2"));
		marcas.add(new Marca(125, "Teste 3"));
		
		return marcas;
	}
	public void saveObject() {  
		if (this.marcaSelecionada != null){
			System.out.println("salvar! Marca: "+marcaSelecionada.getId() + " - " +marcaSelecionada.getDesc());
		} else {
			System.out.println("Marca nula ou não selecionada");
		}
	} 

Ao debugar, na linha 06 da classe ConverterMarca, o “value” vem com o id da opção selecionada na tela. E ao executar a linha 17 do Bean, aparece normal para mim no log “salvar! Marca: 123 - Setado no Converter

Repare que eu fiz sem Primefaces (montei rápido aqui só para auxiliar com o problema). Se tivesse que apostar, seriam duas coisas:

  1. Algum problema relacionado ao Primefaces, seja faltando alguma configuração ou alguma outra coisa. Refaz a sua tela sem usar componentes dele, e veja se funciona.

  2. Verifique o HTML montado da sua página. Olhe se o componente é montado corretamente. Olha só como ficou o desse exemplo que montei:

<select id="cadastro:marca" name="cadastro:marca" size="1"> <option value="123" selected="selected">Teste 1</option> <option value="124">Teste 2</option> <option value="125">Teste 3</option> </select>

E, mais uma vez, recomendo que você debugue o código, e verifique se o fluxo e os valores retornados são os esperados. As vezes o problema pode ser algo simples, mas que só olhando o fonte você não enxerga.

[quote=Alys]Geeh_All,

Qual a sua dúvida/problema neste momento? Dificuldade em conseguir montar um Converter, como sugerido pelo Lucas Abbatepaolo? Você procurou materiais/links? Teve dúvidas neles?

Ou você está com dificuldade em algum outro ponto? Neste caso, qual seria?

Lembre-se que o fórum não é para postar solução de problemas, e sim para te ajudar a resolvê-los.

ahdeerre,

Sim, é possível fazer isso. Procure exemplos de utilização de Ajax. O Showcase do Primefaces tem bosn exemplos.[/quote]

Alys

já tinha visto varios exemplos do showcase, mas nao tinha encontrado nehum exemplo. Ontem estive olhando mais atentamente os exemplos a procura desses que utilizam ajax como você indicou e encontrei esse exemplo que se aproxima do que preciso, porem eles utilizam dois selectOneMenu: http://www.primefaces.org/showcase/ui/pprSelect.jsf

Seria isso mesmo?

Alys ,
Segui sua dica debuguei ,testei e percebi que sempre o meu objeto setado no seleconemenu vai nullo ou seja ele nao recebe a referencia
ate no seu teste que tentei implementar aki deu a mesma coisa

Consegui Galera!!

Brigadão a todos …

o problema era no meu converter e como esta chamando no jsf

vo colocar meu bean, jsf,converter e a classe marca com os metodos equals e hascode sobrescritos

Converter

package implementacoes;

import java.lang.reflect.Field;
import java.util.Collection;

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

@FacesConverter(value="converterMarca")
public class ConverterMarca implements Converter {

	
	@Override  
    public Object getAsObject(FacesContext context,  
        UIComponent component, String value) {  
        if (value == null || value.equals(""))  
            return null;  
  
        try{  
            Long id = Long.valueOf(value);  
            Collection items =  (Collection) component.getAttributes().get("items");  
            return findById(items, id);  
        }catch(Exception ex){  
            throw new ConverterException("Não foi possível aplicar conversão de item com valor ["+value+"] no componente ["+component.getId()+"]", ex);  
        }  
    }  
      
    @Override  
    public String getAsString(FacesContext context, UIComponent component,  
            Object value) {  
        if (value == null)  
            return "";  
          
        return getIdByReflection(value).toString();  
    }  
      
    private Object findById(Collection collection, Long idToFind){  
        for (Object obj : collection){  
             Long id = getIdByReflection(obj);  
             if (id == idToFind)  
                 return obj;  
        }  
          
        return null;  
    }  
      
    private Long getIdByReflection(Object bean){  
        try{  
            Field idField = bean.getClass().getDeclaredField("idMarca");  
            idField.setAccessible(true);  
            return (Long) idField.get(bean);  
        }catch(Exception ex){  
            throw new RuntimeException("Não foi possível obter a propriedade 'idMarca' do item",ex);  
        }  
    }  

}

JSF



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:p="http://primefaces.org/ui">

<h:head></h:head> 
<h:body> 
<h:form id="teste">
<p:commandLink value="Novo Livro"
					actionListener="#{produtobean.prepararAdicionarObject()}"
					onclick="adicionarUsuario.show()" />
					</h:form>
<p:dialog header="Cadastro Usuario" id="newuser"
		widgetVar="adicionarUsuario" dynamic="true" showEffect="slide">

	<h:form id="cadastro">
		<h:panelGrid id="cadastroProduto" columns="2" >
			<h:outputLabel for="produto" value="Produto: " />
			<h:inputText id="produto" value="#{produtobean.produto.produto}"/>
			
			<h:outputLabel for="marca" value="Marca" />  
   				 <h:selectOneMenu id="marca" value="#{produtobean.marcaSelecionada}" converter="converterTeste"
   				 	items="#{produtobean.listamarca}"
   				 >  
        			  <f:selectItems value="#{produtobean.listamarca}" var="marca" itemLabel="#{marca.marca}" itemValue="#{marca}" />
				</h:selectOneMenu>  
				<p:commandButton actionListener="#{produtobean.saveObject()}" value="Cadastrar"/>
		</h:panelGrid>
	</h:form>
	</p:dialog>
</h:body> 
</html>

Bean

package visao;

import implementacoes.InterfaceBean;

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

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.model.SelectItem;

import org.primefaces.event.RowEditEvent;

import dao.MarcaDao;
import dao.ObjectDao;
import entidade.Marca;
import entidade.Produto;


/**
 * Bean da classe Produto responsavel por gerenciar os produtos na cama de visão
 * Como faz conexão com o banco e sai da JVM implementa Serializable.
 * implementa InterfaceBean que tem os metodos basicos dos Bean da aplicação(camada de visão)
 * @author Rangel
 * @version 1.0
 * @since 25/09/2012
 * @see implementacoes.InterfaceBean
 * @see java.lang.Object
 * @see java.io.Serializable
 */
@ManagedBean(name="produtobean")
@RequestScoped
public class ProdutoBean implements Serializable,InterfaceBean {

	/**
	 * numero gerado aleatoriamente pela Serializable 
	 * @serial serialVersionUID
	 */
	private static final long serialVersionUID = -9193715420049605319L;

	private List<Marca> listamarca;
	private ArrayList<SelectItem> marcas;
	
	private Produto produto = new Produto();
	private Marca marcaSelecionada ;
	
	public List<SelectItem> getMarcas(){
			if (marcas == null) {
				
		
		this.marcas = new  ArrayList<SelectItem>();
		if (listamarca == null) {
			listamarca = (List<Marca>) new MarcaDao().listaMarca();
		}
		this.marcas.add(new SelectItem(0,"Selecione"));
		for(Marca m:listamarca){
			this.marcas.add(new SelectItem(m.getIdMarca().toString(),m.getMarca()));
		}
		
			}
		return this.marcas;
	}



	public Produto getProduto() {
		return produto;
	}


	public void setProduto(Produto produto) {
		this.produto = produto;
	}


	public ArrayList<SelectItem> getMarca() {
		return marcas;
	}


	public void setMarca(ArrayList<SelectItem> marca) {
		this.marcas = marca;
	}


	public List<Marca> getListamarca() {
		if (listamarca == null) {
			listamarca = (List<Marca>) new MarcaDao().listaMarca();
		}
		
		return this.listamarca;
	}
	
	public void setListamarca(List<Marca> listamarca) {
		this.listamarca = listamarca;
	}


	public List<Object> listarObject() {
		return null;
	}

	public Object prepararAdicionarObject() {
		produto = new Produto();
		return produto;
	}

	public void editObject(RowEditEvent event) {
		
	}

	public String deleteObject(RowEditEvent event) {
		return null;
	}

	
	public void saveObject() {
		ObjectDao dao = new ObjectDao();
		produto.setMarca(marcaSelecionada);
		dao.saveRelationShip(produto);
	}



	public Marca getMarcaSelecionada() {
		return marcaSelecionada;
	}



	public void setMarcaSelecionada(Marca marcaSelecionada) {
		this.marcaSelecionada = marcaSelecionada;
	}



}

e classe marca

package entidade;

import java.util.*;

import javax.persistence.*;

/**
 * Classe do pacote padrão de entedidades, todas as classes desse pacote foram mapeadas usando jpa2.0
 * Faz um relacionamento OneToMany com a classe Produto
 * @author Rangel
 * @version 2.0
 * @since 03/10/2012
 * @see java.lang.Object
 */
@Entity
@Table(name="marca")
public class Marca {

	
	@Id
	@GeneratedValue
	private Long idMarca;
	
	private String marca;
	
	@OneToMany(mappedBy = "marca", targetEntity = Produto.class, 
				fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	private List<Produto> produto;

	public List<Produto> getProduto() {
		return produto;
	}

	public void setProduto(List<Produto> produto) {
		this.produto = produto;
	}

	public String getMarca() {
		return marca;
	}

	public void setMarca(String marca) {
		this.marca = marca;
	}

	public Long getIdMarca() {
		return idMarca;
	}
	
	
	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
			}
			if (getClass() != obj.getClass()) {
			return false;
			}
			final Marca other = (Marca) obj;
			if (this.idMarca != other.idMarca && (this.idMarca == null || !this.idMarca.equals(other.idMarca))) {
			return false;
			}
			return true;
			}

			@Override
	public int hashCode() {
			int hash = 5;
			hash = 41 * hash + (this.idMarca != null ? this.idMarca.hashCode() : 0);
			return hash;
	}
	
	
}