Java Server Faces

Tengo un problema al llenar un combobox usando JSF mis etiqueta tag es la siguiente:

<h:selectManyListbox value="#{Persona.ciudad}">
           <f:selectItems value="#{Persona.ciudades}"/>
</h:selectManyListbox>

Lo que necesito es llenar tal combobox con las ciudades que tenga en mi base de datos, ya tengo mi bean Persona el cual tienes un atributo "ciudad" de tipo String, de igual forma tengo un atributo "ciudades" de tipo ArrayList, el cual lleno con las ciudades que existen en mi base de datos cuando se manda a llamar su metodo get (getCiudades). El bean ya lo declare en mi faces-config.xml:

 <managed-bean>
        <managed-bean-name>Persona</managed-bean-name>
        <managed-bean-class>beans.Persona</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>

Me manda la siguiente exepcion:

javax.servlet.ServletException: Argument Error: An option for component j_id_id27 was not an instance of javax.faces.model.SelectItem.  Type found: java.util.ArrayList.

Espero me puedan ayudar, gracias de antemano.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de javadicto

Ya pude resolverlo

Ya pude llenar el "h:selectOneMenu" de esta manera:

En el JSP:

<h:selectOneMenu value="#{Persona.ciudad}">
        <f:selectItems value="#{Ciudad.listaCiudades}" />
</h:selectOneMenu>  

En el faces-config.xml:

<managed-bean>
        <managed-bean-name>Ciudad</managed-bean-name>
        <managed-bean-class>beans.Ciudad</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>

    <managed-bean>
        <managed-bean-name>Persona</managed-bean-name>
        <managed-bean-class>beans.Persona</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>

Bean persona:

public class Persona  implements java.io.Serializable {
     private Integer idPersona;
     private Ciudad ciudad;
     private String nombre;
     private String direccion;
     private String telefono;    

    public Persona() {  

    }

    public Persona(Ciudad ciudad, String nombre, String direccion, String telefono) {
       this.ciudad = ciudad;
       this.nombre = nombre;
       this.direccion = direccion;
       this.telefono = telefono;

    }

   

    public Integer getIdPersona() {
        return this.idPersona;
    }
   
    public void setIdPersona(Integer idPersona) {
        this.idPersona = idPersona;
    }
    public Ciudad getCiudad() {
        return this.ciudad;
    }
   
    public void setCiudad(Ciudad ciudad) {
        this.ciudad = ciudad;
    }
    public String getNombre() {
        return this.nombre;
    }
   
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
    public String getDireccion() {
        return this.direccion;
    }
   
    public void setDireccion(String direccion) {
        this.direccion = direccion;
    }
    public String getTelefono() {
        return this.telefono;
    }
   
    public void setTelefono(String telefono) {
        this.telefono = telefono;
    }
}

Bean Ciudad:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.faces.model.SelectItem;

/**
 * Ciudad generated by hbm2java
 */

public class Ciudad  implements java.io.Serializable {

     private Integer idCiudad;
     private String nombre;
     private String estado;
     private Set<Persona> personas = new HashSet<Persona>(0);
     private ArrayList listaCiudades = new ArrayList();

    public Ciudad()
    {
    }

    public Ciudad(String nombre, String estado, Set<Persona> personas) {
       this.nombre = nombre;
       this.estado = estado;
       this.personas = personas;
    }

    public ArrayList getListaCiudades() {        
       
        List<Ciudad> ciudades = new dao.Metodos().getCiudades();
        listaCiudades.clear();

        for(int i=0; i<ciudades.size(); i++)
        {
            Ciudad ciu = new Ciudad();
            ciu = (Ciudad)ciudades.get(i);
           
            listaCiudades.add(new SelectItem(ciu,ciu.getNombre()));
        }      
       
        return listaCiudades;
    }

    public void setListaCiudades(ArrayList listaCiudades) {
        this.listaCiudades = listaCiudades;
    }

    public Integer getIdCiudad() {
        return this.idCiudad;
    }
   
    public void setIdCiudad(Integer idCiudad) {
        this.idCiudad = idCiudad;
    }
    public String getNombre() {
        return this.nombre;
    }
   
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
    public String getEstado() {
        return this.estado;
    }
   
    public void setEstado(String estado) {
        this.estado = estado;
    }
    public Set<Persona> getPersonas() {
        return this.personas;
    }
   
    public void setPersonas(Set<Persona> personas) {
        this.personas = personas;
    }
}

Tengo algunas dudas: Estoy integrando JSF y Hibernate en una aplicacion de ejemplo.

1. Es correcto que el metogo getListaCiudades llene el combo?, si es asi por que se manda a llamar dos veces en el JSP lo que genera que se llene mi combo con datos repetidos? ( Lo solucione limpiando mi ArrayList "listaCiudades").

2. Es correcto que use los mismo beans de mapeo del hibernate como beans de respaldo de JSF?

3. Alguien tiene algun manual o tutorial donde expliquen como integrar Hibernate con JSF?

Re: JSF y Hibernate

¡Gracias por publicar la respuesta! Ojalá y todos hicieran lo mismo una vez que resolvieran sus problemas. Además los ejemplos son muy legibles. Me gusta este post.

1. Es correcto que el metogo getListaCiudades llene el combo?, si es asi por que se manda a llamar dos veces en el JSP lo que genera que se llene mi combo con datos repetidos? ( Lo solucione limpiando mi ArrayList "listaCiudades").

¿Estás aseguro que se manda llamar dos veces? Yo creo que no es así.

2. Es correcto que use los mismo beans de mapeo del hibernate como beans de respaldo de JSF?

Yo lo hago siempre que puedo. Me gusta programar orientado a objetos, donde una clase encapsula datos y comportamiento. Detesto los beans tontos que nada más tienen datos y los beans "procedurales" que sólo tienen comportamiento.

3. Alguien tiene algun manual o tutorial donde expliquen como integrar Hibernate con JSF?

Mejor usa Seam Framework, ya ambos vienen integrados muy bien.

Saludos

Javier Castañón

Imagen de javadicto

Gracias por contestar.

Con respecto a la primera pregunta (Es correcto que el metogo getListaCiudades llene el combo?), en mi JSP tengo esto:

<h:selectOneMenu value="#{Persona.ciudad}">
        <f:selectItems value="#{Ciudad.listaCiudades}" />
</h:selectOneMenu>  

ciudad es un atributo del Bean Persona y listaCiudades es un atributo del Bean Ciudad, hasta aqui todo bien. Bueno quiero entender que ciudad y listaCiudad por defecto van a sus respectivos metodos getter's, si antes fueron seteados muentran informacion si no aparecen vacios ok, bueno en el metodo "getListaCiudades()" recupero desde mi base de datos las ciudades para mostrarlas en el combo, pero me muestra datos repetidos, si en mi base tenia tres ciudades me aparecen seis dos de cada una, lo resolvi haciendole un .crear() a mi lista de ciudades antes de consultarlas para que esto no me pasara, pero no se si esto este bien por que cada ves que se cargue el respectivo JSP hara una consulta a la Base de Datos y si en mi formulario tengo 10 combos, serian 10 consultas a la Base cada ves que se recargue el JSP.

Es correcto que el metogo

Es correcto que el metogo getListaCiudades llene el combo?

Sí, es correcto, lo que es horrible es que en cada llamada al método te des una vuelta a la base de datos. Si aparecen datos repetidos es probablemente algo de lo que debas culpar a tu DAO. Tal vez Hibernate ya había llenado la lista, y tu DAO es el que los repite.

Saludos

Javier

Imagen de javadicto

Otro problema con el combo :(

Tengo el siguiente problema, mi combo ya se llena de manera correcta como lo mencione anteriormente. Pero cuando quiero ontener los valores de mi formulario me genera el siguiente problema:

sourceId=j_id_id16:j_id_id28[severity=(ERROR 2), summary=(Error de conversion en el valor puesto 'beans.Ciudad@7c233a' del modelo 'null Converter'.), detail=(Error de conversion en el valor puesto 'beans.Ciudad@7c233a' del modelo 'null Converter': excepción de: {2})];|WARNING: FacesMessage(s) have been enqueued, but may not have been displayed.

sourceId=j_id_id16:j_id_id28[severity=(ERROR 2), summary=(Error de conversion en el valor puesto 'beans.Ciudad@7c233a' del modelo 'null Converter'.), detail=(Error de conversion en el valor puesto 'beans.Ciudad@7c233a' del modelo 'null Converter': excepción de: {2})]

En mi JSP tengo lo siguiente:

<f:view>
            <h:form>

                <p>Nombre: <h:inputText value="#{Persona.nombre}" /></p>
                <p>Direccion: <h:inputText value="#{Persona.direccion}" /></p>
                <p>Telefono: <h:inputText value="#{Persona.telefono}" /></p>

                <p>Ciudad:
                    <h:selectOneMenu value="#{Persona.ciudad}">
                        <f:selectItems value="#{Persona.listaCiudades}" />
                </h:selectOneMenu>
                </p>
                <br>
                <h:commandButton  id="submit"  value="Submit" action="#{Persona.submit}">
                </h:commandButton>
               
            </h:form>
        </f:view>

En Persona.submit solo tengo unos Systems.out.println() para imprimir lo que el usuario ingreso al formulario funciona si al formulario le quito el combo, por lo cual deduzco que el problema se encuentra ahi, Persona.ciudad es de Tipo Ciudad y Persona.listaCiudades es un ArrayList con objetos de tipo Ciudad, no entiendo cual es mi error :(

Imagen de daxter3000

Paquete DAO

Buenas, me podeis hacer un poco la idea de lo que contiene el metodo getCiudades, es que aparece en el paquete dao.Metodos.getCiudades y no me aclaro muy bien.

Gracias!!