viernes, 24 de abril de 2009

Día 58: EJB y JSF (16ªP) / JBoss-Seam (9ºP)

En la página del login el seam ya tiene preinstalado unos componentes. Los campos de texto usa "credentials" y el chekbox y el botón de "Identity".
Identity es de sesión
Credentials es de evento


@Out



Consejos:
Los EntityManager no funcionará nunca si una clase no es un EJB


---Entrada incompleta---

jueves, 23 de abril de 2009

Día 57: EJB y JSF (15ªP) / JBoss-Seam (8ºP)

Proyecto final del curso
Hoy comenzamos con el plan del proyecto para la evaluación del curso.

El proyecto consiste en los ejercicios que hemos ido haciendo ultimamente desde hace una semana y pico, pero mejorarlos para que:

Componentes obligatorios:
  • Menu de navegación
  • Mensajes a usuarios
  • Login de consola
  • Gestion de excepciones
  • Consultas JPQL
  • Edición de entidades
Todo esto en las horas de clase, que incluyendo las de hoy hacen un total de 24h.

miércoles, 22 de abril de 2009

Día 56: EJB y JSF (14ªP) / JBoss-Seam (7ºP)

Hoy repasamos los interceptores que dimos el lunes y despues terminamos el ejercicio pendiente.
Sobre todo mirar página 174 del pdf "seam_reference"


Los interceptores sirve por ejemplo para:
La seguridad
Para las estadisticas
Para el Logging

(grafico del cuaderno del dia 56)
En la clase A se crea por ejemplo:

Coche coche = new Coche();
Usuario usuario = new Usuario();
usuario.setCoche(coche);
usuario.arranca();

Un objeto (A) envia un mensaje a otro objeto (B)

Primero crear objeto tipo estadistica. Tiene un objeto tipo disco
despues un objeto disco, la relacion entre ellos es N en estadisticas y en disco 1. Tiene una lista de estadisticas.




lunes, 20 de abril de 2009

Día 55: EJB y JSF (13ªP) / JBoss-Seam (6ºP)

Hoy vamos a realizar una modificación a lo que hemos hecho ya antes y que ahora una entidad tambien cumpla la función de un ejb.



Invocacion = llamar a un método


Mirar página 174 del manual del seam "seam_reference.pdf"


Crear una anotacion.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Interceptors(Espia.class)
public @interface EspiaAnotacion {

}

Si la clase espia detecta que el usuario no esta logueado lo redigirá a la pagina del login.

import org.jboss.seam.Component;
import org.jboss.seam.security.Identity;
Identity identity = (Identity) Component.getInstance("org.jboss.seam.security.identity");
boolean isloggedIn = identity.hasRole("admin");


viernes, 17 de abril de 2009

Día 54: EJB y JSF (12ªP) / JBoss-Seam (5ºP)


Ejercicio1
El objetivo del ejercicio de ahora es, que modificando el ejercicio de ayer, que el enlace de edición vaya a una acción de un ejb y que esa acción rellene un objeto de tipo Disco gracias a un componente, una clase, que hemos creado que se enlaza a la lista, y que nos rediriga a la página de edición simplemente llamando a su url, sin ninguna acción más ya que el disco ya lo tiene.
  • Duplicamos los bean (y sus interfaces): ListaDiscoBean y EditaDiscoBean y en los xhtml igualmente pero en el de lista de disco quitamos el parametro al s:link, o mejor dicho... quitamos el s:link completo y usamos mejor un h:commandButton o un h:commandLink con la acción redirigiendola a "EditaDiscoBean2"
  • Creamos una clase java, que se llame "MiComponente" con una anotación anteponiendo la clase: "@Name("miComp")".
    Le añadimos como atributo: "HtmlDataTable tabla" con sus métodos getter y setter y creamos su método principal:
    public String selecciona(){
    Object o = tabla.getRowData();
    Disco d =(Disco) o;
    return null;
    }
  • Creamos ahora el ejb con la acción que estaba enlazada la lista con el "editar"
    Lo nuevo en esta clase es que hay un objeto del tipo componente que hemos creado antes y con una anotación que lo hace dependiente:
    @In(value="miComp",create=true)
    MiComponente miComponente;

    Y su método principal:
    public String selecciona(){
    disco=(Disco) miComponente.getTabla().getRowData();
    System.out.println(">>>>>>>>>Nombre del disco: "+disco.getNombre()+"!!!!!!!!!!!!!!!!!!");
    return "/editaDisco2.xhtml";
    }

    El return puede devolver directamente la url o podria devolver un valor y poner una regla de navegación en el "pages.xml"
  • Para que a la hora de probar los enlaces la consola no se nos vaya disparada por las consultas sql que se nos muestra editaremos el archivo "persistence.xml" usando el buscador de archivos del eclipse y editamos la propiedad "hibernate.show_sql" a false

Ejercicio2
El objetivo de este segundo ejercicio es el de hacer lo mismo pero con las clases que creamos hace unos dias, específicamente con la clase "Cliente"
Hacer una lista de clientes, que haya un enlace y que se pueda editar.
Como "novedad" usaremos el mismo componente, así que simplemente duplicamos los métodos que nos hagan falta pero para la clase Cliente

Pseudo-Ejercicio3
Bueno, esto es ya a modo personal, no me enteré bien en su día y no lo llegé a hacer pero hoy si me he enterado y lo he hecho.
El objetivo del ejercicio es que a la hora de editar un disco también aparezca un menú desplegable para cambiarle su autor y que se guarde.
Podemos cojer el ejercicio 1 de hoy y mejorarlo con esto.
  • La clase "ListaDiscosBean2":
    • Añadir un nuevo Query en el método de carga que seleccione todos los cantantes.
    • Añadir también una lista de cantantes y su método getter y "subirlo" a la interfaz.
  • La página "listaDiscos2.xhtml":
    • Añadir a la tabla una columna nueva para ver el nombre del cantante (para comprobar que se ha guardado): #{d.cantante.nombre}
  • La página "editaDisco2.xhtml"
    • Añadir el select teniendo cuidado al nombre de la variable que le pongamos para mostrar la lista.
    • Primer nivel// h:selectOneMenu value="#{editaDisco2.disco.cantante}" required="true"
    • Segundo nivel// s:selectItems value="#{listaDiscos2.listaCant} var="_cantante" label="#{_cantante.nombre}" noselectionlabel="#{Selecciona cantante}" \\ cierre
    • Segundo nivel// s:convertEntity \\ cierre
    • \\cierre del primer nivel
  • En la clase persistente "Cantante" añadir el Hashcode y el equals


Consejo:
No nos olvidemos del atajo de eclipse: Control+Shift+R para buscar un archivo que no sepamos donde está!!!

jueves, 16 de abril de 2009

Día 53: EJB y JSF (11ªP) / JBoss-Seam (4ºP)

Cambio de JBoss 5.0 Server a JBoss 4.2 Server

Al comenzar el día lo primero que hicimos fue cambiar la versión del servidor JBoss ya que la versión 5 que hemos estado utilizando presenta muchos fallos y mucho coñazo a la hora de los errores y de intentar arreglarlos.
Para cambiarnos de servidor con el proyecto que estamos usando ("seamcea") lo copiamos a JAVA/servers (que lo pusimos en el escritorio) y en el eclipse creamos un nuevo servidor desde la pestaña de servidores, se selecciona el directorio y lo reconocerá, también habrá que añadirle el proyecto y lo más importante el archivo .xml que es el datasource.
Con el servidor bien puesto ya solo hace falta configurar el proyecto al servidor para ello botón secundario encima del proyecto principal, propiedades y "Targeted Runtime" y marcaremos la versión del nuevo jboss.

Un modelo se carga a traves de acciones.
Una acción la llamamos de 2 maneras, desde el pages.xml que se llamara la accion cada vez que recargemos la pagina y a traves de un s:link que es solo 1 vez.
En el pages.xml podemos tener una condicion para limitar la carga.
La vida (SCOPE) de un modelo:
  • Por ahora usamos la vida de sesion.
  • Tambien existe de por conversacion o tarea del usuario.
    Si por ejemplo pulsamos en un enlace para editar algo es una tarea y se guarda ahi. La ventaja seria tener varias ventanas y cada ventana una tarea y varias tareas a la vez. Otra ventaja es la limpieza, que una vez terminemos con nuestra "conversacion", nuestra tarea, llamamos al método con la anotación @End y todo lo que conlleve la conversación se limpiará, se quedará a nulo.
    Tampoco hay que olvidarse de poner una etiqueta (Anotacion) nueva @Begin en el/los método/s principal/es (el de cargar o buscar algo), solo funcionara si es de tipo conversación. Después del @Begin hay que añadir un "join=false" si no queremos que las conversaciones se pisen (que abramos una segunda ventana para editar un segundo disco y cuando editamos el primero, éste pise al segundo.)
    La etiqueta @End se pondran en el/los metodo/s que termine/n la conversación/es.


Ejercicio:
Cambiar el scope del ejercicio de ayer de sesion a conversación y probar si funciona y añadir el @Begin con el join.

Para validar un calendario
rich:calendar value=... validator="#{bean.valida}"

@Name("bean")
public class MiBean{
public void valida(FacesContext fc, UIComponent ucom,Object o) throws exception{
Date fechaSel=(Date) o;
if(fechaSel) throw Excetion();
}
}


Para validar un input text cerramos la etiqueta a parte y como cuerpo le ponemos una etiqueta del tipo f:validate


miércoles, 15 de abril de 2009

Día 52: EJB y JSF (10ªP) / JBoss-Seam (3ºP)

Hoy comenzamos con un repaso al JPA (lo de las clases persistentes) porque según una encuesta al principio de la clase es lo que más cuesta.

Ejercicio:
El objetivo del ejercicio es realizar más clases persistentes y que se reflejen en la base de datos sin problemas.

  • Primero creamos una clase "Cliente"
    • Debe tener precediendo el nombre de la clase las anotaciones @Entity y @Table(name="clientes") (Puse el nombre de la tabla en plural porque ya existía una del mismo nombre y así en el resto de clases de este ejercicio)
    • La clase debe implementar la clase "Serializable"
    • Crear un atributo de tipo "Long" que es el "id", un atributo "String nombre" y un conjunto de pedidos "Set pedidos"
    • Crear sus getter y setter y precediendo a los getter añadir unas anotaciones:
      • Método getId: @Id y @GeneratedValue
      • Método getPedidos: @OneToMany(mappedBy="cliente"), la tabla clientes estará relacionada con la tabla pedidos como 1-n
      • El resto de métodos: @Column
  • Después creamos la clase "Pedido"
    • Igualmente que en la clase "Cliente" y el nombre de la tabla será "pedidos"
    • Los atributos son "Long id", "Date fecha", "Cliente cliente" y "Set lineas"
    • Las anotacciones encima de los getter:
      • Método getId: @Id y @GeneratedValue
      • Método getCliente: @ManyToOne, y así terminamos la relación con la tabla cliente.
      • Método getLineas: @OneToMany(mappedBy="pedido"), la tabla pedido se relaciona con la tabla lineapedido como 1-n
      • El resto de métodos: @Column
  • Por último creamos la clase "LineaPedido"
    • Lo mismo que en las anteriores y el nombre de la tabla es "lineapedidos"
    • Los atributos son "Long id", "Integer cantidad", "Pedido pedido",y "Disco disco"
    • Las anotaciones encima de los getter:
      • Método getId: @Id y @GeneratedValue
      • Método getPedido y método getDisco: @ManyToOne, ya que la tabla lineapedido termina la relación con pedido y también con la tabla disco (que ya esta creada de ejercicios de días anteriores y que se debe crear en la clase "Disco" su atributo lineas que es un conjunto de LineasPedido y sus métodos y su @OneToMany)

Ejercicio 2:

Lo de ahora consiste en mostrar una lista de discos, con un enlace cada uno y que cada enlace rediriga a una página para editar el nombre del disco.

Editar fecha usando rich:calendar (La fecha situada en el disco) y la fecha nueva que no sea posterior a la fecha de hoy.
Menu desplegable, grupo de musica, discos.

Modelo de rich calendar
Para añadir un calendario teniendo de base la fecha del objeto:
rich:calendar value="#{editaDisco.disco.fecha}" popup="false" datePattern="YY-MM-dd HH:mm" cellwidth="24px" cellHeight="22px" style="width:200px"/

Para añadir un desplegable:
h:selectOneMenu value="#{editaDisco.disco.cantante}"
s:selectItems value="#{listaCantantes.lista}" var="cantante" label="#{cantante.nombre}" noselectionlabel="Selecciona Cantante..."/
s:convertEntity/
/h:selectOneMenu

martes, 14 de abril de 2009

Día 51: EJB y JSF (9ªP) / JBoss-Seam (2ºP)

Una de las cosas buenas de lo que estamos haciendo ahora es que antes hacíamos los mapeos mediante archivos xml y ahora usamos anotaciones.

Spring vs EJB (Seam)


Ejercicio:
Terminamos el ejercicio de ayer pero con la añadidura que ahora pasemos a editar.
Repaso todos los pasos para hacer el ejercicio hasta la edición.
El objetivo del ejercicio completo es crear una página que introduzcamos el nombre de un cantante y nos aparezca una tabla con la lista de discos que tiene y en la tabla haber un enlace que rediriga a una página que lo edite y ahí editar el nombre del disco y que permanezca en la base de datos el cambio.
Pasos:
  1. Crear una interfaz y una clase que implemente algunos métodos como:
    • String begin() con una anotación @Begin precediéndolo con un log.info marcando el inicio de la conversación.
    • String end() con una anotación @End precediéndolo con un log.info marcando el fin de la conversación.
    • void destroy() con las anotaciones @Destroy y @Remove precediéndolo.
    • String increment() que será el método principal para buscar un disco dado un nombre aportado por el formulario, para ello crearemos un query usando un entityManager (que debe de tener la anotación @PersistenceContext) y también una lista simple para recojer todos los discos que devuelva la consulta con sus métodos get..() y set..() que también deben de estar en la interfaz.
  2. En la clase implementación no se nos debe olvidar poner el estado y el nombre para ello usaremos las anotaciones @StateFul y @Name("cantante")
  3. Crear un ".xhtml" que será la vista y que nos muestre el formulario inicial para buscar un cantante y que después también nos mostrará la tabla con los discos del cantante.
    Para el formulario de búsqueda del cantante:
    • Primero usamos un encabezado h1 poniendo la propiedad de la clase implementación que queramos mostrar, por ejemplo el nombre, que creamos un String nombre en la clase con sus get y set: #{cantante.nombre}
    • Colocamos la entrada de texto usando h:inputText y de valor la misma propiedad
    • Finalmente colocamos un h:commandButton que es el encargado de asociar el valor del formulario con la acción de la clase. En el botón usaremos el action="#{cantante.increment}" y ya debería encontrarnos y mostrarnos de forma simple el cantante que queramos.
    Para mostrar la lista de discos del cantante:
    • En la misma página usaremos un h:dataTable de valor la propiedad de la clase que hicimos que era una lista simple: value="#{cantante.resultados}" y nombramos una variable para acceder a él: var="discos"
    • En la tabla, antes de cerrar la etiqueta, colocamos las columnas que queramos mostrar, el nombre del cantante, el id, el nombre y un enlace especial para la edición del disco que queramos. h:column>#{discos.cantante.nombre}<
    • El enlace sería usando la etiqueta s:link y la acción es la de una clase que tendremos que hacer que sería el método principal para mostrar el disco seleccionado y un view="/editaDisco.xhtml" que redirigirá a una nueva página.
    • Antes de cerrar el enlace usamos una etiqueta f:param de nombre id y de valor discos.id, que lo que hará es pasar el id del disco por parámetro para que la página de edición encuentre el disco marcado.
  4. Creamos una interfaz y su implementación y pondremos casi los mismos métodos, no los mismos, el principal seria inicia() y otro secundario guarda()
    • El método inicia() usa un log.info("") para saber que va bien y guardamos en un objeto de tipo Disco el resultado de este método: entityManager.find(Disco.class,id); que lo que hace es devolver un objeto de tipo Disco dado un id, que es el id que pasamos antes por enlace.
    • El método guarda() simplemente llama al método merge() del entityManager metiendole el disco para que se guarde en la base de datos.
  5. Para la vista crearemos la página editaDisco.xhtml con un inputText y un commandButton al mismo estilo como hicimos en la otra vista.



En el resto del día hicimos ejercicios parecidos.

lunes, 13 de abril de 2009

Día 50: EJB y JSF (8ªP) / JBoss-Seam (1ºP)

JBoss-Seam
Para facilitar EJB
Utiliza ANT

Más información AQUÍ

Lo utilizaremos para facilitarnos el desarrollo de proyectos que utilicen JSF y EJB

Primer proyecto seam
Creamos un nuevo proyecto, de tipo "seam web project"
Lo llamaremos "seamcea"
De target runtime seleccionamos un servidor de aplicaciones "JBoss 5.0 Runtime"
Y en configuración el Seam 2.1 y "Next >"
Nos saltamos las dos siguientes con "Next >"

En Seam Runtime le añadimos el seam que nos daron que hemos copiado en el workspace (jboss-seam-2.1.1.GA)
Seleccionamos el despliege de tipo EAR = EJB
Seleccionamos la base de datos y le añadimos un nuevo perfil de conexión. A la altura de los "Drivers" pulsamos el botón "New Driver definition". En Name/Type seleccionamos el mysql versión 5 y en el jar lo borramos y buscamos el que tiene el JBoss (el servidor) en default/lib y al aceptar le decimos que base de datos acceder su contraseña y demás.
Después de terminar el perfil de conexión marcamos la 2ª casilla que recree la base de datos.
Cambiamos el nombre de los paquetes que queden de tal manera "es.cea.seamcea.session", "es.cea...."
Y ya estará.

Se crearán 4 proyectos que son en realidad el mismo. El proyecto principal ya se autopublicará en el servidor JBoss y para que a la hora de que se publiquen cualquier cambio que hagamos hacemos doble click en el servidor y en "publishing" le decimos que revise si hay cambios a cada segundo.

Dentro del proyecto "seamcea-ejb" en el sourceFolder ejbModule en el paquete que tiene le damos boton derecho, Seam Action y creamos una nueva acción "miAccion" de método "saluda" y de página "bienvenida".
Con esto se creará de forma automática una acción con su bean y un xhtml que muestra una página de bienvenida con un botón que muestra una cadena al pulsar.
Para practicar un poquito duplicamos el método de "saluda()" y lo renombramos a "despedida()" tanto en la implementación (MiAccionBean) como en la interfaz (MiAccion) y añadimos un nuevo CommandButton en "bienvenida.xhtml"

De ahora en adelante una acción es una clase sin estado "Stateless". Nos crea una interfaz local con un EJB y su página.
Una clase con estado (Statefull) se le llama conversación.

En el proyecto "seamcea-ejb" creamos una nueva conversación y lo llamamos contador. Con esto hará lo mismo que antes pero hay que comenzar incrementar lo que se quiera y terminar.

El servidor jboss se encarga de mantener vivo un componente con estado para que cada usuario tenga el suyo mientras que uno sin estado lo crea y destruye. Los con estado ya son serializables.

Una clase con estado debe de ser serializable, con la anotación Destroy y Remove.
Existen varios estados: De Evento, de página, de conversación y de sesión.
Estos estados se pueden especificar con la anotación "@Scope(ScopeType.X)"

Borramos la librería de discografica-hibernate de la carpeta "deploy" del JBoss y copiamos el paquete "com.enjava.discografica.model" al source folder del proyecto ejb del que estamos trabajando.
Borramos las líneas de las propiedades de catalogo y de esquema en persistence.xml y realizamos un full publish.

Ejercicio:
El objetivo del ejercicio es hacer lo mismo de antes, crear un bean con una acción y una página, pero en vez de forma automatizada, hacerlo de forma manual.
Pasos:
  • Crear la interfaz con las cabeceras de los métodos. No nos olvidemos de los métodos "begin", "end" y "destroy" con las anotaciones @Begin, @End y "@Destroy @Remove" que son esenciales (sobre todo el último método) para el funcionamiento de todo.
  • Implementar la interfaz. Crear un método "increment" que incremente un valor y mediante un query que consulte un nombre dado en la tabla cantantes.
  • Crear la página .xhtml mostrando los datos.


viernes, 3 de abril de 2009

Día 49: JSF (7ª parte)

Modelo de objetos -> JSF -> web - ...html

binding: es cuando una etiqueta de un archivo .xhtml, un jsf, está representado en el código java de una clase.

Hoy empezamos con un ejemplo de "bindeo" de una página xhtml con una clase java y que al rellenar el formulario ocurría una acción que se mostraba en la página.
  • Primero crear un archivo .xhtml, que lo llamaremos "ejemplo.xhtml"
  • Incluir en un formulario una etiqueta outputText, inputText y commandButton
  • En cada etiqueta que estará asociado a un objeto le añadimos una propiedad a la etiqueta que es "binding" y la asociamos al nombre del objeto de la clase que esté.
  • Les añadimos un value y debería quedar tal que así: "h:commandButton binding="#{ejemploAction.miBoton}" action="#{ejemploAction.pulsar}" value="No me toques!""
  • Crear la clase "EjemploAction" que será la que contenga las acciones y los elementos del formulario.
  • Cada elemento estará asociado a un objeto, por ejemplo el "commandButton" de antes: "HtmlCommandButton miBoton;" y tendrá un método llamado pulsar que gestionará los objetos del formulario.

Eventos en JSF
ActionEvent -> Cuando una acción ocurre. Propiedad en las etiquetas CommandButton: actionListener
ValueChangeEvent -> Cuando un valor cambia.
Propiedad en las etiquetas: valueChangeListener

jueves, 2 de abril de 2009

Día 48: EJB (7ª Parte) y JSF (6ª parte)

Si queremos inyectar un valor de un parametro hacemos lo de siempre pero con el value de tal forma: "#{param.id}" (id, por ejemplo)

Hoy continuamos con los ejercicios de siempre y esta vez que haya un buscador de canciones dado un disco además de que en la tabla que aparezca de los resultados nos muestre un enlace especial de tipo "h:commandLink" que haga una acción y que se muestren los detalles de la canción.

miércoles, 1 de abril de 2009

Día 47: EJB (6ª Parte) y JSF (5ª parte)

Siempre que hagamos algún cambio en nuestros proyectos de JSF, EJB o JPA debemos hacer en la consola "mvn clean install"

Formulario de busqueda de disco por nombre. Llama a una página que muestra los datos del disco encontrado.
Formulario por nombre del disco y nombre del autor.

Antes de acabar la clase: hacer pruebas en aislamiento en el EJB, en el JPA y en el JSF y usando el mockito.


Hoy terminamos el ejercicio que dejamos ayer pendiente sobre la búsqueda del disco y del cantante.
Este ejercicio lo hice a mi manera y me funciona, pero se puede hacer de otra manera.
Los pasos para que funcione son los siguientes:

JPA (Java Persistence API) >Usado en el proyecto
"discografía-hibernate" // Saber Más
  • Tener la clase "Disco" creada implementando "Serializable" con sus parámetros: id, nombre, cantante (de tipo Cantante) y canciones (Conjunto de Canciones) con sus anotaciones "@Entity" y "@Table" al comienzo de la clase y las anotaciones "@Id" y "@GeneratedValue" en el método getter del Id y "@Column" en los getter del resto de parámetros.
  • Tener la clase "Cantante" creada, implementando también "Serializable" y sus parámetros son: id, nombre y discos (Conjunto de Discos) y con las mismas anotaciones de "Disco"
  • Vamos a la consola y limpiamos del repositorio el proyecto y lo volvemos a instalar introduciendo el comando mvn clean install (C:\workspace\discografica-hibernate>mvn clean install)

EJB (Enterprise JavaBeans) >Usado en el proyecto "ejbProject" // Saber Más
  • Primeramente debemos tener creada la interfaz "DiscograficaDAORemote" encabezando los métodos para buscar un cantante introduciendole un nombre y devolviendo un "Cantante" y otro método para buscar un disco que le introducimos el nombre del disco y el nombre del cantante y devolviendo un "Disco"
  • Creamos la clase "DiscograficaDAO" que implemente la interfaz "DiscograficaDAORemote" y rellenando los métodos de búsqueda.
    El método para buscar el cantante quedaría así:
    • Query query = entityManager.createQuery("" +
      "from Cantante ca where " +
      "ca.nombre=:nombre");
      query.setParameter("nombre", nombre);
      try{
      Cantante resultadoConsulta = (Cantante) query.getSingleResult();
      return resultadoConsulta;
      }catch (NoResultException e) {
      e.printStackTrace();
      return null;
      }

    El método para buscar el Disco quedaría así:
    • Query query = entityManager.createQuery(""
      "from Disco d " +
      "where d.nombre=:nombreDisco and " +
      "d.cantante.nombre=:nombreCantante");
      query.setParameter("nombreDisco", nombreDisco);
      query.setParameter("nombreCantante", nombreCantante);
      try{
      Disco resultadoConsulta = (Disco) query.getSingleResult();
      return resultadoConsulta;
      }catch (NoResultException e) {
      e.printStackTrace();
      return null;
      }
  • Vamos a la consola, en este proyecto y realizamos un "mvn clean install"

JSF (JavaServer Faces) >usado en el proyecto "jsf1" // Saber Más
  • Primero creamos un archivo ".xhtml" en "src/main/webapp" que será el que muestre un formulario de la búsqueda. Hacemos 2 formularios con distintos id.
    Formulario 1:
    • Usando la etiqueta de jsf "h:inputText" le introducimos un valor "#{busquedaBean.cantante.nombre}" que lo que hace es rellenar una propiedad de una clase llamada "BusquedaBean" y que el campo sea requerido y al final un "h:commandButton" de action: "#{busquedaAction.busca1}" que lo que hará será llamar un método de una clase llamada "BusquedaAction"
    Formulario 2:
    • Lo mismo que el primer formulario pero que introduzca el nombre del disco.
  • Creamos una clase llamada "BusquedaBean" que tenga como atributos cantante (de tipo Cantante) y disco (de tipo Disco) con sus métodos getter y setter.
  • Creamos una clase llamada "BusquedaAction" que será la que enlazará con el EJB DiscograficaDAO y sus métodos.
    Añadimos un método que será el que recoja de forma remota la clase DiscograficaDAO, lo hacemos método porque el código es algo engorroso y feo:
    • private DiscograficaDAORemote getDiscograficaDAO() throws NamingException {
      Properties p = new Properties();
      p.put(Context.INITIAL_CONTEXT_FACTORY,
      "org.jnp.interfaces.NamingContextFactory");
      p.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
      p.put(Context.PROVIDER_URL, "jnp://localhost:1099");
      Context ctx = new InitialContext(p);
      Object ref = ctx.lookup("DiscograficaDAO/remote");
      DiscograficaDAORemote discograficaDAORemote = (DiscograficaDAORemote) PortableRemoteObject
      .narrow(ref, DiscograficaDAORemote.class);
      return discograficaDAORemote;
      }

    Creamos los métodos que llaman los formularios que a su vez llaman a los métodos que creamos de búsqueda en el EJB DiscograficaDAO
    También tendrá como atributo la clase "BusquedaBean" que creamos antes y que usaremos aquí. Por ejemplo el método para buscar un cantante:
    • public String busca1(){ //Buscar el cantante
      DiscograficaDAORemote discograficaDAORemote;
      try {
      discograficaDAORemote = getDiscograficaDAO();
      } catch (NamingException e) {
      throw new RuntimeException(e);
      }
      Cantante cantante = discograficaDAORemote
      .buscaCant(busquedaBean.getCantante().getNombre());
      if(cantante!=null)
      return ("cantanteEncontrado");
      else
      return("cantanteNEncontrado");
      }
  • Lo siguiente sería enlazar y asignar un nombre al Bean y a las acciones y que el formulario de la página lo use. Para ello tenemos que editar el archivo de configuración "my-config.xml" situado en "src/main/webapp/WEB-INF"
    • Añadimos una etiqueta "managed-bean" y le asignamos un nombre "busquedaBean", seleccionamos la clase (en cuál paquete está ubicado y el nombre de la clase) y que tenga un tiempo de vida de tipo petición.
    • Hacemos de nuevo lo mismo pero de nombre "busquedaAction" y le añadimos una propiedad (managed-property) que de nombre es el bean (busquedaBean) y de valor (value) sera "#{busquedaBean}". Con esto lo que estamos haciendo es que se inyecte la clase bean en la clase de la accion ya que necesitamos de ella.
  • En este proyecto no hace falta hacer la instalación


Ejercicio
Ampliamos nuestro ejercicio y esta vez en vez de solamente hacer una búsqueda que borre y guarde en la base de datos.