Programación en castellano
Inicio > Tutoriales > Lenguajes orientados a objeto > J2EE > Construir Aplicaciones EJB con JBoss, Lomboz y Eclipse
-Tutoriales

Construir Aplicaciones EJB con JBoss, Lomboz y Eclipse


Crear un Bean de Entidad BMP

Este capítulo describe como crear un componente EJB con Persistencia Manejada por el Bean (BMP). Crearemos dos beans BMP, Customer y Manager. El bean Customer será responsable de almacenar los datalles de los clientes de MyStore. El bean Manager almacena detalles de los managers de MyStore. Ambos beans se comunican con sus respectivas tablas de la base de datos utilizando Data Access Objects (DAOs) llamados CustomerDAO y ManagerDAO respectivamente.

A todos los clientes se les ha asignado un único customerID para propósitos de almacenamiento en MyStore además de su nombre de usuario para acceder a los servicios. De forma similar a los Managers de MyStore se les ha asignado un único ManagerID.

Nota:
La práctica usual para acceder a los métodos de negocio de beans BMP, es utilizar un bean de sesión, que encapsule la lógica de negocio y actúe como interface para otros componentes EJB. En este caso se puede acceder a Customer y a Manager mediante StoreAccess.

Esta aproximación viene de un patrón de diseño llamado Session Facade, donde los beans enterprise encapsulan la lógica y los datos de negocio y exponen sus interfaces. El bean de sesión actúa como una fachada (Facade) para encapsular la complejidad de las interacciones con los beans de bajo nivel. El session facade es responsable de manejar los objetos de negocio y de proporciona una abstracción uniforme de los servicios de negocio a los clientes de la capa de presentacion, por lo tanto, oculta la implementación de los objetos de negocio en los beans de bajo nivel.

Este tutorial utiliza este patrón para la implementación de la capa de negocio.

. Crear el Bean de Entidad BMP - Customer:

  • Ve a Package Explorer y expande el nodo Expand Mystore; selecciona src, pulsa con el botón derecho y aparecerá un menú.
  • En el menú selecciona New > Lomboz EJB Creation Wizard.
  • Introduce au.com.tusc.bmp como nombre del paquete, Customer como el nombre del bean y selecciona el tipo de Bean como Bean Manged Entity, por último pulsa Finish.

    Esto creará un paquete llamado au.com.tusc.bmp dentro de src y el bean CustomerBean dentro de ese paquete:

    Nota:
    Esto generará el nombre del bean, el nombre JNDI y el tipo del bean. También añade la palabra Bean al nombre del fichero.

    Como has podido ver en la figura anterior se ha creado una etiqueta a nivel de clase @ejb.bean, que tiene asignado el tipo del bean, su nombre y su nombre JNDI que se generará en el interface Home. Esta etiqueta también generará los descriptores de despliegue en los ficheros ejb-jar.xml y jboss.xml cuando generemos las clases.

  • Ahora vamos a generar todos los interfaces, incluyendo Home, Remote y DAO y otras clases de ayuda. No necesitamos especificar ninguna etiqueta en ejbGenerate.xml ya que ya lo hicimos para el módulo MyStoreMgr en páginas anteriores.

  • Ve al nodo CustomerBean en au.com.tusc.bmp > LombozJ2EE > Add EJB to Module, selecciona MyStoreMgr y pulsa OK.
  • Ve al nodo MyStoreMgr > LombozJ2EE > Generate EJB classes.
    Nota:
    Todos estos pasos se han visto en páginas anteriores, si tienes algún problema no dudes en volver a leerlos.

Ahora veamos los ficheros que ha generado Xdoclet. Como se muestra en la siguiente figura hay dos nuevos ficheros llamado CustomerData y CustomerPK además de los que añadimos para nuestros beans de sesión. También tenemos un CustomerBMP que extiende la clase CustomerBean. El resto de ficheros deberían serte familares...

Como discutimos en páginas enteriores sobre las distintas etiquetas ejbDoclet usadas en ejbGenerate.xml, para generar estas clases, CustomerData y CutomerPk se generan mediante las etiquetas del siguiente fragmento de código de ejbGenerate.xml:

Las etiquetas importantes son <dataobject/> y <entitypk/>.

Nota:
No hay clase CustomerDAO, ya que no hemos generado este fichero especificando la etiqueta dao en la clase CustomerBean.

. Crear el Interace DAO del Cliente (Customer):

Como vamos a utilizar un DAO para acceder a la base de datos, tenemos que crear una clase DAOImpl para proporcionar una implementación para el interface DAO generado.

  • Ve a src > package au.com.tusc.dao, añade una clase CustomerDAOImpl:
  • Ahora ve a tu clase bean y declara esta etiqueta a nivel de clase (es decir en la parte superior) como se muestra abajo, para generar el interface DAO:
    @ejb.dao class="au.com.tusc.bmp.CustomerDAO"
    impl-class="au.com.tusc.dao.CustomerDAOImpl"
    
  • Regenera tus clases y chequea que se ha generado el interface DAO:
    Nota:
    Ok, OK!, como referencia aquí tienes los pasos que tienes que seguir:
    1. Expande el nodo MyStoreMgr en el proyecto MyStore en el Package Explorer.
    2. Pulsa con el botón derecho y aparecerá un menú desplegable.
    3. Ve a Lomboz J2EE > Generate EJB

    Abajo puedes ver el interface DAO generado:

    Si miramos la clase DAO generada, veremos que tiene cuatro métodos más que la de StoreAccess (que era para un bean de sesión sin estado) cuando se generó por primera vez (es decir, antes de añadirle la etiqueta a nivel de método @dao:call(.

    Nota:
    Merece la pena mencionar aquí que los beans de entidad con persistencia manejada por el bean no necesitan la etiqueta @dao:call para generar los métodos del interface DAO.

    Todos estos métodos se han generado a partir de la etiqueta descrita anteriormente para la generación del interface DAO, como se ve abajo:

    También podemos ver los descriptores generados hasta este paso, en ejb-jar.xml dentro de MyStoreMgr/META-INF.

    Estos descriptores se han generado mediante la siguiente etiqueta en CustomerBean:

    @ejb.bean name="Customer"
    jndi-name="CustomerBean"
    type="BMP"
    

    Esta etiqueta también genera los descriptores en jboss.xml, que cubriremos más adelante.

  • El siguiente paso es añadir atributos/propiedades a nuestro bean Customer, a las que podrán acceder los clientes a través del interface remoto utilizando los métodos get y set. Estos atributos son mapeados a las correspondientes columnas en una tabla de la base de datos.

  • Para poder añadir estas propiedades/atributos, define todos los atributos (private para encapsularlos) y sus correspondientes métodos accesores (get y set). Cada método accesor (get) tendra dos etiquetas o tres en el caso de una clave primaria. Los métodos mutadores (set) sólo tendrán una etiqueta.
  • Añade estas etiquetas para los atributos/propiedades (en términos de bean):
    /** 
        * Returns the customerID
        * @return the customerID
        * 
        * @ejb.persistence 
        * @ejb.pk-field 
        * @ejb.interface-method
        */
        public  java.lang.String getCustomerID() {
             return customerID ;
        }
    
        /**
         * Sets the customerID
         * @param java.lang.String the new customerID value
         *  
         * @ejb.interface-method
         */
        public void setCustomerID (java.lang.String customerID)    
             this.customerID = customerID;
    }
    

    Ahora analicemos estas etiquetas:

    1. @ejb.persistence especifica éste como un atributo persistente. Todos los métodos accesores y mutadores se sobreescribirán en la clase BMP generada, en este caso es CustomerBMP, y todos los métodos accesores y mutadores tendrá una bandera en el ítem, ya que la persistencia es controlada por ejbLoad() y ejbStore().
    2. @ejb.pk-field especifica que este atributo está mapeado a una clave primaria en la base de datos y es asignado como clave primaria en la clase PrimaryKey, en este caso la clase CustomerPK.
    3. @ejb.interface genera estos métodos en el interface remoto.

    Ahora, en el caso de los métodos mutadores (como setCustomerID) la única referencia requerida es @ejb.interface-method para generar este método en el interface remoto.

    De forma similar, añade los métodos y sus etiquetas para el resto de campos persistentes. No hay etiqueta @ejb.pk-field ya que customerID es la clave primaria.

    Nota:
    En el caso de una clave primaria compuesta tienes que especificar etiquetas @ejb.pk-field para todos los atributos/propiedades que crean la clave compuesta.

    De forma similar, añade las etiquetas y métodos para el resto de campos persistentes, que en este caso son firstName, lastName, Address, phone y shareholderStatus como se ve en el siguiente fragmento de código de CustomerBean.

  • Regenera las clases EJB y examina qué métodos se han generado en las distintas clases, particularmente en CustomerBMP y en CustomerData.

. Añadir Métodos de Búsqueda:

Ahora añadiremos unos métodos de búsqueda para nuestra clase Bean.

  • Añade un método con esta firma:
    public CustomerPK ejbFindByPrimaryKey(CustomerPK pk) throws FinderException
  • Pon algunas sentencias de depuración y devuelve null como se ve abajo:

    Ahora cuando regeneremos nuestras clases EJB se sobreescribirá este método en CustomerBMP. Este método también llamará al correspondiente método del interface CustomerDAO como se ve en el siguiente fragmento de código de CustomerBMP:

    Esto también creará los métodos en el interface Home y en el interface del DAO, como se ve en las siguientes figuras:

  • Añade otro método finder a CustomerBean, con la siguiente firma:
    public CustomerPK ejbFindByUserID (String userID) throws FinderException
  • Pon algunas sentencias de depuración y devuelve null:
    Nota:
    Según lo establece la especificación EJB 12.8.1, todos los métodos finder deberían devolver la clave primaria.
  • Regerenera de nuevo tus clases EJB, y se crearán los métodos en el interface CustomerHome, en CustomerBMP y en CustomerDAO, de forma similar a los creados para ejbFindByPrimaryKey.

. Añadir Métodos de Negocio:

  • Ahora, añade un método de negocio con la firma y con el tipo de interface como Local:
    Nota:
    Los pasos para añadir un método de negocio se vieron en páginas anteriores. Hemos elegido el tipo de interface como local porque estos métodos serán invocados desde la misma JVM. En este caso, serán invocados por el bean de sesión sin estado StoreAccess.
  • Esto proporcionará los detalles para un cliente individual. Añade algunas sentencias de depuración y devuelve un ejemplar de CustomerData como se muestra en el siguiente fragmento de código de CustomerBean.
  • Asegurate de regenerar las clases EJB otra vez, antes de implementar el interface del DAO del cliente.

. Implementar el Interface DAO del Cliente:

Ahora implementemos nuestros métodos en la clase CustomerDAOImpl. Esta clase del paquete au.com.tusc.dao implementa los métodos generados en la clase CustomerDAO del paquete au.com.tusc.bmp.

  • Primero importa los siguiente paquetes:
    javax.naming.InitialContext;
    javax.sql.DataSource;
    java.sql.Connection;
    java.sql.PreparedStatement;
    java.sql.ResultSet;
    java.sql.SQLException;
    
  • Modifica la declaración de tu clase para que CustomerDAOImpl implemente CustomerDAO.
  • Añade un campo para almacenar la referencia a la factoría de recursos JDBC:
    private DataSource jdbcFactory;
  • En el método init(), busca la referencia jdbc/DefaultDS utilizando el API JNDI, y almacenala en la variable jdbcFactory.

    El string de búsqueda es java:comp/env/jdbc/DefaultDS.

  • En el método load(), primero obtén una conexión a la base de datos utilizando jdbcFactory. Crea una sentencia SQL que busque un registro correspondiente a customerid en la tabla Customer, donde customerid es la clave primaria:
  • En el método store(), primero obtén una conexión a la base de datos utilizando jdbcFactory. Crea una sentencia SQL que actualice un registro correspondiente a customerid en la tabla Customer, donde customerid es la clave primaria:
  • En el método ejbFindByUserID(), primero obtén una conexión a la base de datos utilizando jdbcFactory. Crea una sentencia SQL que busque el customerid correspondiente a un userid dado en la tabla Customer, donde customerid es la clave primaria:
  • En el método ejbfindByPrimaryKeystore(), primero obtén una conexión a la base de datos utilizando jdbcFactory. Crea una sentencia SQL que busque un registro correspondiente a customerid en la tabla Customer, donde customerid es la clave primaria y devuelve la clave primaria:
  • También deberías implementar métodos para borrar y crear. Dejaremos esto como un ejercicio para tí (seguro que tendrás idea de como hacerlo!), o puedes dejarlos como esqueletos, según la siguiente figura:
  • Hemos terminado nuestra clase CustomerDAOImpl. Regenera de nuevos las clases EJB.

    Después de regerenar las clases EJB, veamos los interfaces Home Local y Remote Local:

    En el interface Remote Local (que en este caso es CustomerLocal), se ha expuesto un método de negocio, y el resto de métodos son para acceder a los atributos/propiedades del bean (ya que declaramos estos métodos como métodos de interface en CustomerBean), como se ve abajo. Estos métodos los ha generado la etiqueta @ejb.interface-method.

    En el interface Home Local (que en este caso es CustomerLocalHome), hay dos métodos finder. También ha generado JNDI_NAME y COMP_NAME (nombre lógico para buscar el componente).

    Estos nombres se han generado utilizando la etiqueta declarada en CustomerBean:

    Nota:
    Actualmente no estámos interesados en el interface Customer (que es un interface remoto) ni en CustomerHome (que es un interface home remoto), porque estámos accediendo a los métodos del bean desde la misma máquina virtual Java, por eso, sólo necesitamos interfaces locales.

    Nota:
    En CustomerBean no hemos implementado ningún método para configurar el contexto, porque lo genera Xdoclet en la clase CustomerBMP, como se ve en la siguiente figura:

    Ahora el Bean Customer y su implementación DAO están completos y podemos desplegar este bean.

. Desplegar el Bean Customer:

Para poder desplegar este bean tenemos que añadirle unos cuantos descriptores de despliegue. Añadiremos las dos etiquetas mostradas abajo:

  • Primero añade la siguiente etiqueta a nivel de clase en CustomerBean.
    @ejb.resource-ref res-ref-name="jdbc/DefaultDS"
    res-type="javax.sql.Datasource"
    res-auth="Container"
    

    Esta etiqueta generará los descriptores de despliegue en ejb-jar.xml, ya que el bean tiene que saber a que datasource va a conectarse, y cuál es su tipo, etc. Esto generará los descriptores mostrados en la siguiente figura:

  • Añade esta segunda etiqueta requerida por el servidor de aplicaciones JBOSS:
    @jboss.resource-ref res-ref-name="jdbc/DefaultDS"
     jndi-name="java:/DefaultDS"
    

    Esta etiqueta generará los descriptores de despliegue en jboss.xml, ya que el servidor de aplicaciones necesita conocer el nombre JNDI del datasource que se ha registrado. Estos generará los siguientes descriptores de despliegue:

  • Ahora que todo está completo, es hora de desplegar el bean. Por eso, regenera de nuevo las clases EJB.
  • Ve a Lomboz J2EE View y expande el nodo MyStore > MyStoreMgr y selecciona Jboss 3.2.1 ALL .
  • Pulsa con el botón derecho y seleciona Debug Sever en el menú que aparece.
    Nota:
    Esto es para arrancar el servidor, si tu servidor ya está ejecutándose, saltate este paso y ve al siguiente.
  • Ve al nodo MyStoreMgr en LombozJ2EE view, pulsa con el botón derecho y selecciona Deploy en el menú que aparece:

    Los mensajes de la consola te dirán si tu bean se ha desplegado con éxito o no.

Ahora que nuestro bean Customer está terminado, para poder crear un cliente que invoque operaciones sobre este bean tenemos que hacer algunas modificaciones a nuestro bean StoreAccess.

Nota:
Como pudiste ver en el diagrama que hay al principio de la página, el cliente invocará operaciones sobre el bean Customer a través de StoreAccesBean, es una buena práctica acceder a los beans de entidad de esta forma. Como resultado necesitamos una vista local del bean del cliente en vez de una vista remota, porque ámbos están en la misma máquina virtual Java.

. Añadir un Método Create a StoreAccess:

En el bean StoreAccess añadiremos un método ejbCreate, que creará un bean de entidad BMP (en este caso Customer) con la siguiente firma:

public void ejbCreate() throws javax.ejb.CreateException
  • Primero, añade un campo para almacenar la referencia obtenida al buscar el Customer en JNDI:
    private CustomerLocalHome customerLocalHome;
    
  • En el método ejbCreate almacena la referencia en la variable customerLocalHome llamando al método estático getLocalHome de la clase CustomerUtil como se ve en el siguiente fragmento de StoreAccess:

. Añadir un Método de Negocio en StoreAccess:

Añadiremos otro método de negocio en StoreAccess que invocará el correspondiente método de negocio del bean Customer.

  • Ahora, añade un método de negocio con la siguiente firma public CustomerData getCustomerData(String userID) y el tipo de interface como Remoto. Como los clientes entrarán en el sistema con su username, una vez autenticados serán identificados por el userid y podrán recuperar los detalles de su cuenta en MyStore utilizando este userid.
  • Ahora invoca a los métodos finder de Customer con la variable que hemos creado en el método ejbCreate:
    CustomerLocal myCustomer  =   customerLocalHome.findByUserID(userID)
  • Ahora invoca el método de negocio de Customer utilizando la variable myCustomer:
    CustomerData cd = myCustomer.getCustomerData() 

    Abajo puedes ver un fragmento de este método de negocio:

Ya se han añadido a StoreAccess todos los métodos para acceder a los métodos de negocio de Customer. Sólo nos quedan los descriptores de despligue necesarios para enlazar/referenciar los beans StoreAccess y Customer. Añadiremos estas dos etiquetas:

  • Primero añade esta etiqueta a nivel de clase en el bean StoreAccess:
    @ejb.ejb-ref ejb-name="Customer"
     view-type="local"
     ref-name="CustomerLocal"
    

    Esta etiqueta generará los descriptores de despliegue en ejb-jar.xml, como StoreAccessBean tiene saber a qué bean está referenciando, y cuál es su tipo de vista y su nombre de referencia. Esto generará los siguientes descriptores de despliegue.

    Nota:
    El tipo de vista es local porque ámbos beans están en la misma JVM, de lo contrario sería remoto. Observa que ref-name se ha generado como CustomerLocalHome en vez de como CustomerHome. Se generán los dos pero nosotros estámos utilizando Local en este caso.
  • Ahora añade la segunda etiqueta a nivel de clase en el bean StoreAccess:
    @jboss.ejb-ref-jndi ref-name="CustomerLocal"
    jndi-name="CustomerLocal"
    

    Esta etiqueta generará los descriptores de despliegue en jboss.xml, ya que el servidor de aplicaciones tiene que conocer el nombre JNDI del bean Customer con el que se ha registrado. Estos son los descriptores generados:

    Nota:
    Como podemos ver en el fragmento de código anterior, el descriptor de despliegue generado por la etiqueta @jboss es erróneo, porque la referencia local del Customer de la etiqueta <ejb-ref> debería ser lt;ejb-local-ref>.

    Esto parece ser un bug de esta etiqueta, por eso lo corregiremos manualmente cambiando la etiqueta en el fichero jboss.xml como se ve abajo:

    Precaución aquí: asegúrate de hacer este cambio después de terminar de regenerar tus clases EJB, porque cada vez que las regeneres, jboss.xml inicialmente tendrá los descriptores erróneos generados por esta etiqueta.

Ahora hemos terminado de modificar el bean StoreAccess, despliegua el bean de nuevo desde la vista Lomboz J2EE. Los pasos para hacer esto se han visto en página anteriores. En la consola podrás ver los mensajes que muestran el estado del despliegue.

Una vez que el bean se ha desplegado con éxito, crea un test de cliente que invocará el método loginUser sobre StoreAccessBean y getCustomerData sobre CustomerBean.

. Crear tu Test de Cliente:

  • Ve al nodo Project MytStore, selecciona el nodo src y expándelo, selecciona el paquete au.com.tusc.client y pulsa con el botón derecho.
  • Selecciona New en el menú y selecciona Lomboz EJB Test Client Wizard.
  • Selecciona au.com.tusc.client como el nombre del paquete, SessionBMPClient como el nombre, au.com.tusc.session.StoreAccessHome como el EJB Home y au.com.tusc.session.StoreAccess como EJB Interface:

    Esto generará los métodos necesarios en tu clase SessionBMPClient y simplemente debes invocar los métodos loginUser y getCustomerData como se ve abajo:

  • Ahora añade algún codigo a tu cliente. Añade estas línes en el método testBean:
    System.out.println("Request from client : ");
    String userID = myBean.loginUser("ANDY","PASSWD");
    System.out.println("Reply from Server: Your userid is " + userID );
    CustomerData cd = myBean.getCustomerData(userID); 
    System.out.println ("Andy your details with MyStore are " + cd );
    

. Probar el Cliente:

  • Ahora para poder probar tu cliente, selecciona el nodo SessionBMPClient, ve al menú superior y selecciona el icono del 'hombre corriendo'.
  • Sobre él, selecciona Run as, y selecciona Java Application:

Ahora en tu consola, si tu respuesta para ANDY es U2 y si los detalles para el CustomerID son C2, tu llamada habrá tenido éxito:

. Ejercicio:

Aquí tienes un ejercicio para tí. Para seguir progresando, implementa Manager como un bean de entidad BMP similar a Customer, con los mismos comportamientos. Te ayudaremos con un listado de las tareas:

  1. Crea un bean BMP llamado Manager en el paquete au.com.tusc.bmp.
  2. Crea una clase DAO llamada ManagerDAOImpl en el paquete au.com.tusc.dao.
  3. Añade todos los atributos/propiedades de ManagerBean, añade los métodos accesores/mutadores para cada atributo.
  4. Añade un método find llamado ejbFindByPrimaryKey con la firma:
    ejbFindByPrimaryKey (MangerPK pk) throws FinderException.
  5. Añade un método find llamado ejbFindByUserID con la firma:
    public MangerPK ejbFindByUserID (String userID) throws FinderException
  6. Añade un método de negocio llamado getManagerData con la firma:
    public ManagerData getManagerData()
  7. Implementa los métodos en la clase ManagerDAOImpl. El string de búsqueda requerido por el API JNDI es "java:comp/env/jdbc/DefaultDS".
  8. Despliega el Bean.
  9. Añade un campo al bean StoreAccess para almacenar la referencia después de buscar el manager en JNDI.
    private ManagerLocalHome manager LocalHome;
  10. En el método ejbCreate del bean StoreAccess almacena la referencia a la variable managerLocalHome llamando al método estático getLocalHome de ManagerUtil.
  11. Añade un método de negocio al bean StoreAccess:
    public MangerData getManagerData(String userID)
  12. Añade las siguientes etiquetas de despliegue a nivel de clase para enlazar/referenciar Manager:
    1. @ejb.ejb-ref ejb-name="Manager"
         view-type="local"
         ref-name="ManagerLocal"
     
    2.  @jboss.ejb-ref-jndi ref-name="ManagerLocal"
          jndi-name="ManagerLocal" 
    
  13. Prueba tu bean Manager ejecutando tu test de cliente creado para Customer llamado SessionBMPClient.
Nota:
No olvides corregir los descriptores generados en jboss.xml como se mencionó antes en relación al bean Customer.

Nota:
Todos estos pasos son los mismos que para el bean Customer. Implementa este bean que utilizaremos en siguientes páginas.

Nota:
En el caso de que no puedas hacerlo, aquí te proporcionamos las clases:
 
Patrocinados
 

Copyright © 1999-2007 Programación en castellano. Todos los derechos reservados.
Formulario de Contacto - Datos legales - Publicidad
Mantenida por: Claudio y Dani.

Hospedaje web y servidores dedicados linux por Ferca Network

red internet: jugar gratis | amor | navidad 2009 | registro de dominios | servidores dedicados
más internet: comprar | gratis | posicionamiento en buscadores | decoración libre | gifs animados