Valor esquisito retornado pelo Bean

No h:selectManyMenu deveria retornar uma lista com os valores vindos do banco de dados, mas o que aparece é apenas um valor tipo beans.CadastradorBean@1e48948

O trecho do código da página xhtml é esse:

<h:selectManyMenu id="cadastradorSelect">
<f:selectItems value="#{cadastradorC.lista}" />
</h:selectManyMenu><h:message for="cadastradorSelect" /

Trecho da Classe do CadastradorControlador:

...
private List lista;
   public List getLista() throws Exception {
      CadastradorDAO dao = new CadastradorDAO();
      this.lista = dao.getTodosCadastradores();
      return this.lista;
   }
...

O trecho da Classe CadastradorDao, que é usado pelo CadastradorControlador:

public List getTodosCadastradores() throws Exception {
...       
    try {
         connection = this.conn; 
         ps = connection.prepareStatement("SELECT nome FROM cadastradores");
         rs = ps.executeQuery();
         List<CadastradorBean> lista = new ArrayList<CadastradorBean>();
         while(rs.next()) {
            String nome = rs.getString(1);
            lista.add(new CadastradorBean(nome));
         }
         return lista;
      }
...

Na Classe CadastradorBean, há vários construtores, sendo que o que é utilizado pelo CadastradorDao (nesse caso) é esse:

  ...  
   private String id; 
   private String nome;
   private String senha;
    
   public CadastradorBean(String nome) {
      this.nome = nome;    
   }
  ...

Meu arquivo facex-config.xml:

<managed-bean>
        <managed-bean-name>cadastrador</managed-bean-name>
        <managed-bean-class>beans.CadastradorBean</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
    
    <managed-bean>
        <managed-bean-name>cadastradorC</managed-bean-name>
        <managed-bean-class>controladores.CadastradorControlador</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>

Alguém consegue ver onde estou errando? Qualquer ajuda seria bem vinda, estou começando ainda com o JSF…
Desde já, obrigado!

Esse é o retorno do método toString padrão. Para arrumar isso vc tem algumas opções:

Sobrescreve o método toString na classe CadastradorBean para exibir um nome mais simples:

class CadastradorBean { public String toString() { return this.nome; // Por exemplo } }

Ou altera o f:selectItems informando o atributo da descrição do select:

<f:selectItems value="#{cadastradorC.lista}" var="c" itemLabel="#{c.nome}" />

Thanks in advance, lsjunior.

Vou testar aqui, qualquer coisa aviso!

Funcionou, obrigado!

Mudei para SelectOneMenu para dar o resultado que eu queria.

Ficou assim:

<h:selectOneMenu id="cadastradorSelect">
<f:selectItems value="#{cadastradorC.lista}" var="c" itemLabel="#{c.nome}" />
</h:selectOneMenu><h:message for="cadastradorSelect" />

Valeu lsjunior, pela paciência!

Tem que ver como vc fez, pelo bean ou pelo f:selectItems.

Para capturar o valor selecionado pelo usuário, é aqui que deve estar a captura?

<h:selectOneMenu id="cadastradorSelect" value="#{beanQueVaiGuardarCadastrador.nome}">

Valeu!

Sim, só fica atendo para o tipo.

Se vc tem um bean tipo esse:

class Pessoa { Integer id; String nome; }

E faz isso:

<h:selectOneMenu id="pessoa" value="#{cadastroBean.pessoa}"> <f:selectItems value="#{pessoaBean.pessoas}" var="p" itemLabel="#{p.nome}" /> </h:selectOneMenu>
O CadastroBean deve ser assim:

class CadastroBean { void setPessoa(Pessoa pessoa)... }

Mas se faz isso:

<h:selectOneMenu id="pessoa" value="#{cadastroBean.pessoaId}"> <f:selectItems value="#{pessoaBean.pessoas}" var="p" itemValue="#{p.id}" itemLabel="#{p.nome}" /><!-- O valor é o ID --> </h:selectOneMenu>
O CadastroBean deve ser assim:

class CadastroBean { void setPessoaId(Integer pessoaId)... }

lsjunior, obrigado. Você comentou uma futura dúvida minha.

Existe um tabela no BD para o Cadastrador, e outra para o Cliente. Porém, na tabela Cliente, existe uma chave estrangeira que aponta para o ID do Cadastrador. Não existe Cliente sem um Cadastrador associado a ele.

Então, no formulário do cadastro do Cliente, é obrigatório escolher um Cadastrador. Daí minha necessidade de exibir todos os Cadastradores nesse SELECT. Entretanto, estou exibindo os NOMES, e através do DAO/CONTROLADOR/ETC teria que buscar o ID correspondente aquele NOME do Cadastrador.

Com Scriptlets/JSP (HTML puro) era mais “fácil”, por assim dizer, pois no SELECT do HTML simples, eu exibia os nomes para o usuário, porém, o valor do SELECT era o ID relativo ao nome.

Como estou usando JSF/PrimeFaces, ainda vou verificar como aplico essa “técnica”. :slight_smile:

Imagino que seja o que você colocou no código:

<f:selectItems value="#{pessoaBean.pessoas}" var="p" itemValue="#{p.id}" itemLabel="#{p.nome}" /><!-- O valor é o ID -->  

É por aí… Vou testar…
Obrigado pela paciência!

Na verdade postei para vc ver que pode definir diretamente como Bean, no caso Pessoa, ou como um tipo nativo. O problema de colocar como Bean é que vc deve criar um Converter para o JSF saber o que fazer quando pegar o valor da tela e voltar para o Java.

Continuando:

<h:selectOneMenu id="pessoa" value="#{cadastroBean.pessoa}" converter="pessoaConverter"> <!-- Adicionamos o converter --> <f:selectItems value="#{pessoaBean.pessoas}" var="p" itemLabel="#{p.nome}" /> </h:selectOneMenu>

[code]@FacesConverter(value = “pessoaConverter”)
public class PessoaConverter implements Converter {

@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
	Pessoa pessoa = new Pessoa();
	pessoa.setId(Integer.valueOf(value)); // Ou pega do banco
	return pessoa;
}

@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
	Pessoa pessoa = (Pessoa) value;
	return pessoa.getId().toString();
}	

}[/code]

Eu acho dessa forma um saco de fazer, prefiro setar as propriedades em tipos ‘nativos’ e recuperar apenas os necessários. No seu caso tanto para ver o valor atual no select como para setar no bean vc não precisa da Pessoa em si, apenas do identificador.