JSF e os Objetos no <h:selectOneMenu <RESOLVIDO>

Boa Tarde,

o que acontece é que tenho um Select assim:

 
&lt;h:selectOneMenu value="#{projetoManaged.projeto.cliente.codCliente}"  valueChangeListener="# {projetoManaged.valueChangeListener}" immediate="true" &gt;
                        
                        &lt;f:selectItems value="#{projetoManaged.clientes}" var="cliente" itemLabel="#{cliente.codCliente}" itemValue="#{cliente.codCliente}"/&gt;
                    &lt;/h:selectOneMenu&gt;

porém ele sempre tá retornando null isso: itemValue="#{cliente.codCliente}

não consigui fazer funcionar dessa forma com selectItems… sabendo que a lista não está vazia pois meu Bean coloca a lista correta como:

[code] for (Cliente cliente : c) {
clientes.add(new SelectItem(cliente, cliente.getNome()));

    }[/code]

quando faço assim:

&lt;f:selectItem itemLabel="a" itemValue="a"/&gt; &lt;f:selectItem itemLabel="b" itemValue="b"/&gt; &lt;f:selectItem itemLabel="c" itemValue="c"/&gt;

funciona perfeitamente!

alguém sabe onde possso estar errando? ou um esclarecimento mehor do JSF!

Não sei se eu te entendi direito, tente return uma lista de objetos do tipo Cliente, da maneira que você está construindo
o seu SelectOne você não precisa converter os dados para SelectItem. Confirma ai se você está usando JSF 2 ou 1.2.

Se não funcionar posta um pouco mais de código, porque esse ai não esclareceu muito.

estou usando JSF 2.

esse é meu Bean Gerenciado:

[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package br.kmf.controller;

import br.kmf.bean.Cliente;
import br.kmf.bean.Projeto;
import br.kmf.dao.GenericDAOImpl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

/**
*

  • @author Bruno
    */
    public class ProjetoManaged implements Serializable {

    private Projeto projeto;

    public List<SelectItem> clientes = new ArrayList<SelectItem>();
    private Cliente cliente = new Cliente();
    private String cliente1;

    /** Creates a new instance of ProjetoManaged */
    public ProjetoManaged() {
    projeto = new Projeto();
    projeto.setCliente(cliente);
    }

    /**

    • @return the projeto
      */
      public Projeto getProjeto() {
      return projeto;
      }

    /**

    • @param projeto the projeto to set
      */
      public void setProjeto(Projeto projeto) {
      this.projeto = projeto;
      }

    public void cadastrar(ActionEvent event) {

     System.out.println("Aquiiii: "+ cliente.getCodCliente());
       System.out.println("Aquiiii: "+ cliente1);
     GenericDAOImpl&lt;Projeto, Integer&gt; dao = new GenericDAOImpl();
     this.projeto = dao.save(projeto);
     FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Informacao:", "Projeto " + projeto.getDescricao() + ",  cadastrado com Sucesso!"));
    

    }

    public List<SelectItem> getClientes() {

     List&lt;Cliente&gt; c = new ArrayList&lt;Cliente&gt;();
    
     GenericDAOImpl&lt;Cliente, Integer&gt; dao = new GenericDAOImpl();
     c = dao.getAll(new Cliente());
    
     for (Cliente cliente : c) {
         clientes.add(new SelectItem(cliente, cliente.getNome()));
    
     }
    
     return clientes;
    

    }

    public void valueChangeListener(ValueChangeEvent event) {
    System.out.println("Cliente: " + event.getNewValue());

     PhaseId phaseId = event.getPhaseId();
     //pega o novo valor
     Integer newValue = (Integer) event.getNewValue();
     if (phaseId.equals(PhaseId.ANY_PHASE)) {
         //agenda o evento para a fase que nos interessa
         event.setPhaseId(PhaseId.UPDATE_MODEL_VALUES);
         event.queue();
     } else if (phaseId.equals(PhaseId.UPDATE_MODEL_VALUES)) {
         //aqui vai o método de antes (um pouco mudado)
         
         this.cliente.setCodCliente(newValue);
         cliente1 = String.valueOf(newValue);
     }
    

    }

    /**

    • @return the cliente
      */
      public Cliente getCliente() {
      return cliente;
      }

    /**

    • @param cliente the cliente to set
      */
      public void setCliente(Cliente cliente) {
      this.cliente = cliente;
      }

    /**

    • @return the cliente1
      */
      public String getCliente1() {
      return cliente1;
      }

    /**

    • @param cliente1 the cliente1 to set
      */
      public void setCliente1(String cliente1) {
      this.cliente1 = cliente1;
      }

}
[/code]

tem algumas coisas como esse cliente1 que tava colocando pra testar!

e minha pagina:

[code]<?xml version=‘1.0’ encoding=‘UTF-8’ ?>
<!DOCTYPE composition PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<ui:composition xmlns:ui=“http://java.sun.com/jsf/facelets
xmlns:h=“http://java.sun.com/jsf/html
xmlns:p=“http://primefaces.prime.com.tr/ui
template="/template/template.xhtml"
xmlns:f=“http://java.sun.com/jsf/core”>

&lt;ui:define name="top"&gt;&lt;/ui:define&gt;

&lt;ui:define name="content"&gt;

    &lt;h:form&gt;
        &lt;p:messages id="messages" showDetail="true"/&gt;

        &lt;p:panel header="Projetos"&gt;

            &lt;h:panelGrid columns="2" &gt;
                &lt;h:outputText value="Descricao: "/&gt;
                &lt;h:inputText value="#{projetoManaged.projeto.descricao}"/&gt;

                &lt;h:outputText value="URL: "/&gt;
                &lt;h:inputText value="#{projetoManaged.projeto.url}"/&gt;

                &lt;h:outputText value="Cliente: "/&gt;

                &lt;h:selectOneMenu value="#{projetoManaged.cliente.codCliente}"  valueChangeListener="#{projetoManaged.valueChangeListener}" immediate="true" &gt;
                    &lt;f:selectItems value="#{projetoManaged.clientes}" var="cliente" itemLabel="#{cliente.nome}" itemValue="#{cliente.codCliente}"/&gt;
                &lt;/h:selectOneMenu&gt;
            &lt;/h:panelGrid&gt;

            &lt;p:commandButton value="Cadastrar" actionListener="#{projetoManaged.cadastrar}" update="messages"/&gt;
        &lt;/p:panel&gt;

    &lt;/h:form&gt;

&lt;/ui:define&gt;

</ui:composition>
[/code]

a questão é que essa linha <f:selectItems value="#{projetoManaged.clientes}" var=“cliente” itemLabel="#{cliente.nome}" itemValue="#{cliente.codCliente}"/> ele não pega o itemValue. e quando vai Validar o Bean não passa, o que não acontece se eu usar estaticamente o selectItem

Me parece que o seu problema é que o seu método getClientes() está retornando um List mas a sua viu
está tentando acessar os atributos dos items como se esses fossem do tipo Cliente.

Modifique o seu método getClientes() disso:

    public List<SelectItem> getClientes() {  
  
        List<Cliente> c = new ArrayList<Cliente>();  
  
        GenericDAOImpl<Cliente, Integer> dao = new GenericDAOImpl();  
        c = dao.getAll(new Cliente());  
  
        for (Cliente cliente : c) {  
            clientes.add(new SelectItem(cliente, cliente.getNome()));  
  
        }  
  
        return clientes;  
    } 

… para isso:

    public List<Cliente> getClientes() {  
  
        return new GenericDAOImpl().getAll(new Cliente());
  
    } 

… e me avise se funcionou.

funcionou sim. mas algumas questões agora me deixaram na dúvida.

primeiro: da forma que está eu não estou trabalhando com Objetos no selectOne certo??

existe como fazer isso, ou seja no lugar do vaor dele ser o codCliente inteiro ser o objeto Cliente??

outra coisa estranha é que achei que tinha que retornar o SelectItens assim como vi em muitos tutorias do JSF 2. isso mudou do JSF 1.2 e 2??

mas tá funcionando direitinho… so isso que fiquei em duvida agora!

PRIMEIRO:
Sim é possível fazer isso e inclusive é aconselhável que você o faça pois dessa forma o componente vai armazenar os objetos
Cliente ficando mais fácil para escrever um converter que entregue o objeto para o seu ManagedBean e não o código dele. Ai
segue as modificações que você precisa fazer no seu código, apenas o valor do atributo itemValue.

<h:selectOneMenu value="#{projetoManaged.projeto.cliente.codCliente}"  valueChangeListener="# {projetoManaged.valueChangeListener}" immediate="true" >  
    <f:selectItems value="#{projetoManaged.clientes}" var="cliente" itemLabel="#{cliente.codCliente}" itemValue="#{cliente}"/>  
</h:selectOneMenu>

SEGUNDO:
Antes do JSF 2 a tag f:selectItems não possuía os atributos var, itemLabel e itemValue, essas informações eram obtidas através
dos atributos dos objetos SelectItem retornados. O problema, como você pode perceber, é que dessa forma você sempre precisava
converter os objetos das suas listas para SelectItem, o que é massante e trabalhoso. Com esses três atributos é possível que seus
ManagedBeans retornem a lista de dados sem nenhum tipo de processamento prévio, ou seja, assim como ela veio do banco.

blz, dev.rafael, como ficaria pra armazenar os Objetos??

pq quando tento fazer isso ele dá um erro de Null Converter.

Acho que não entendi, o que você quer dizer com “armazenar os Objetos”? Você quer armazena-los onde?
Com relação ao seu erro, poste o stackTrace da sua exceção.

aeciovc Isso é um sistema ? caralho fiquei bolado… muito legal jsf 2

Tu tem mais codigo para postar aqui ? gostaria de dar um Contro C + Control V, para fazer um CRUD.

abraço.


public void cadastrar(ActionEvent event) {  
  
        System.out.println("Aquiiii: "+ cliente.getCodCliente());  
          System.out.println("Aquiiii: "+ cliente1);  
        GenericDAOImpl&lt;Projeto, Integer&gt; dao = new GenericDAOImpl();  
        this.projeto = dao.save(projeto);  
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Informacao:", "Projeto " + projeto.getDescricao() + ",  cadastrado com Sucesso!"));  
  
    }  

da ate pra ver que ta usando Facade !

Cara, vou ver se arranjo um tempo para escrever um artigo e posto ae. Beleza?

blz dev.rafael…

minha questão de armazenar os Objetos é no selectOneMenu mesmo… pq da forma que fiz no meu selectItems eu to usando o ItemValue como cliente.codCliente e não como o Objeto = cliente

entende??

otimo vou ficar aqui no agurado, e estudando sobre o spring

[quote=aeciovc]blz dev.rafael…

minha questão de armazenar os Objetos é no selectOneMenu mesmo… pq da forma que fiz no meu selectItems eu to usando o ItemValue como cliente.codCliente e não como o Objeto = cliente

entende??[/quote]

Caro aeciovc

veja:

  • primeiro crie os metodos hashCode e equals da sua classe cliente
  • Na seu managed bean a classe que retorna a lista pode ser assim:
public List&lt;Cliente&gt; getClientes() {     
  
    return new GenericDAOImpl().getAll(new Cliente());   
  
} 
  • crie uma classe para converter
@FacesConverter(value="converteCliente", forClass=Cliente.class) 
public class ConverteCliente implements Converter {

	@Override
	public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
		return GenericDAOImpl().getCliente(Integer.valueOf(arg2));
	}

	@Override
	public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
		return String.valueOf(((Cliente) arg2).getCodigoCliente());
	}

}
  • e sua pagina

&lt;h:selectOneMenu value="#{projetoManaged.projeto.cliente}"   &gt;     
    &lt;f:selectItems value="#{projetoManaged.clientes}" var="cliente" itemLabel="#{cliente.descricao}" itemValue="#{cliente}"/&gt;     
    &lt;f:converter converterId="converteCliente"/&gt;
&lt;/h:selectOneMenu&gt; 

e pronto.

não sei se fui claro

Flw

tonyam, tentei fazer desta forma como você postou mas não funcionou. Você teria um exemplo com o Dao para eu poder comparar.

obrigado.

Pra quem se interessar, tenho um exemplo sem converter aqui:
codepianist.com/2012/06/exemplo-jsf2-selectcombo-sem-coverter/

Um grande abraço e sucesso! 8)