Categorías destacadas
programacion php    
Artículo
4
¡votar!

 Construir Aplicaciones EJB con JBoss, Lomboz y Eclipse


Crear un Bean de Entidad CMP

Esta página cubre como crear un componente EJB con Persistencia Manejada por el contenedor (CMP). Crearemos dos beans CMP, Item y Supplier. El bean Item será responsable de almacenar los detalles de los ítems, como su disponibilidad o precio. El bean Supplier almacena detalles de los provedores de MyStore. Ambos beans interactúan con las correspondientes tablas de la base de datos. En CMP está interacción la controla el contenedor, en este caso el contenedor JBOSS CMP.

A todos los ítems se les ha asignado un único itemId igual que a los proveedores se les ha asignado un único supplierID además de su username que es lo que usarán para acceder a los servicios de MyStore.

Nota:
La práctica usual para acceder a los métodos de negocio de beans CMP, 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 Items y a Supplier mediante StoreAccess.

. Crear el Bean de Entidad CMP Items:

  • Ve a Package Explorer y expande el nodo Mystore, selecciona src, pulsa el botón derecho y aparecerá un menú desplegable.
  • En el menú pulsa New > Lomboz EJB Creation Wizard.
  • Introduce au.com.tusc.cmp como el nombre del paquete, Item como el nombre del bean, y selecciona el tipo del bean como Container Manged Entity:
  • Pulsa Next y aparecerá una nueva ventana.
  • Introduce MyStoreItem como el Schema Name.
  • Introduce Item como el nombre de la tabla.
  • Bajo Persistent Fields primero introduce itemID como el Field, con un tipo de campo de java.lang.String, ITEMID como su columna Database, y VARCHAR para su tipo SQL.
  • Pulsa Add.. y se añadirá este campo a la sección Fields, selecciona este nuevo campo y pulsa Make Primary Key:
  • De forma similar añade el resto de los campos de la tabla items:
    1. Add .. Field: supplierID, Field Type: java.lang.String, Database Column: SUPPLIERID, SQL Type: VARCHAR.
    2. Add .. Field: description, Field Type: java.lang.String, Database Column: DESCRIPTION, SQL Type: VARCHAR.
    3. Add .. Field: quantity, Field Type: java.lang.Integer, Database Column: QUANTITY, SQL Type: INTEGER.
    4. Add .. Field: price, Field Type: java.lang.Float, Database Column: PRICE, SQL Type: DECIMAL.
  • Después de añadir estos campos, pulsa Finish.

Esto creará un paquete llamado au.com.tusc.cmp bajo src, y se creará ItemBean dentro de ese paquete:

Nota:
En comparación con nuestros anteriores Beans de Entidad BMP, ahora se han generado más etiquetas a nivel de clase. Observa también que el CMP no requiere un interface DAO, ya que la comunicación entre el bean y la base de datos la controla el contenedor.

Primero generamos las clases EJB y luego examinaremos esas etiquetas:

  • Ve al nodo ItemBean en au.com.tusc.cmp > LombozJ2EE > Add EJB to Module, selecciona MyStoreMgr y pulsa Ok.
  • Ve al nodo MyStoreMgr y selecciona LombozJ2EE > Generate EJB classes.

Ahora veamos qué ficheros ha generado Xdoclet. Como puedes ver abajo, los ficheros son casi los mismos que para BMP, excepto que no hay clases de clave primaria o de DAO, y ahora hay un ItemCMP que extiende la clase ItemBean. El resto son los mismos que para los beans de entidad BMP:

Examinemos esas nuevas etiquetas, algunas de las cuales hemos visto en páginas anteriores:

  1. @ejb.bean; proporciona información sobre el EJB. Es la única etiqueta obligatoria para todos los EJBs.
  2. @ejb.persistence; se utiliza a dos niveles, a nivel de clase y de método. A nivel de clases proporciona información sobre la persistencia de un bean de entidad CMP, es decir la tabla de la base de datos con la que va a interactúar, y que le proporcionará la persistencia. A nivel de método proporciona información del mapeo de los atributos persistentes del bean a columnas en la tabla de la base de datos.
  3. @ejb.finder; define un método finder para el interface home. Este requiere la consulta EJB QL para comparar los datos y la firma del método. Esta etiqueta se puede utilizar para varios métodos finder.
  4. @ejb.persistence-field; etiqueta a nivel de método que ha quedado obsoleta en favor de @ejb.persistence, proporciona información sobre los campos persistentes.
  5. @ejb.pk-field; define la clave primaria.

El siguiente fragmento de código muestra como se declaran los atributos persistentes en un bean de entidad CMP:

Nota:
Todos los atributos persistentes se declaran con métodos accesores y mutadores abstract en ItemBean. Observa también que en el caso de una clave primaria compuesta se tiene que especificar la etiqueta @ejb.pk-field para todos los atributos/propiedades que se combinan para forma la clave compuesta.

. Implementar el Método ejbCreate:

El wizard de Lomboz Bean crea el método ejbCreate, pero aún tenemos que añadir algo de código para completarlo. Modificar la firma de ejbCreate, pasar todos los atributos como parámetros y luego seleccionar todos esos atributos utilizando sus métodos mutadores asociados, como se muestra abajo:

Nota de errata:
Hay un error en la siguiente figura. El atributo Integer llamado 'qunatity' debería ser 'quantity'.
Nota:
El otro aspecto interesante de ejbCreate es su tipo de retorno, ya que debe ser el mismo que el tipo de la clave primaria (es decir, tiene que ser String, Integer, Float, o cualquier otro). En este caso es String -- el tipo de itemID, y cuando lo implementemos debería devolver null (puedes ver la especificación 10.5.1 de EJB).

. Añadir un Método Finder:

Nota:
Un interface home de un bean de entidad define uno o más métodos finder, para encontrar un objeto entidad o una colección de ellos. El nombre de cada método finder empieza con el prefijo find, como en findPrice o findQuantity en nuestro caso. Todo método finder, excepto findByPrimaryKey(key) debe estar asociados con un elemento query en el descriptor de despliegue. El preveedor del bean de entidad declara la consulta EJB QL y la asocia con el método finder en el descriptor de despliegue. Un método find normalmente se caracteriza por un string de consulta EJB QL especificado mediante el elemento query.

Ahora añadamos un método finder a nuestra clase bean para buscar ítems suministrados por un proveedor particular. Para poder hacer esto tenemos que declarar la etiqueta a nivel de clase que hemos descrito arriba: @ejb.finder.

  • Añade esta etiqueta:
    @ejb.finder 
    query="SELECT OBJECT(a) FROM MyStoreItem a where a.supplierID = ?1"
    signature="java.util.Collection findBySupplierID(java.lang.String supplierID)"
    
    Nota:
    En EJB QL, en lugar del nombre de la tabla, se utiliza el nombre del esquema (en este caso MyStoreItem, en vez de especificar Item para una consulta SQL). Lo mismo ocurre con los nombres de columnas que se utilizarían en SQL, en EJB QL son reemplazados por los correspondientes atributos declarados en el bean.
  • Regenera tus clases EJB para ver lo que ha creado la etiqueta anterior en el interface Home, tiene que ser algo parecido al siguiente fragmento de código de ItemLocalHome:

    Tiene cuatro métodos, incluyendo los dos métodos finder generados por las etiquetas declaradas a nivel de clase. Los otros dos, create y findByPrimaryKey los crea Xdoclet (mediante la etiqueta <entitycmp/> en ejbGenerate.xml.

  • Añade otro método finder para encontrar todos los ítems que están fuera de stock en MyStore. Añade la siguiente etiqueta:
    @ejb.finder 
    query="SELECT OBJECT(c) FROM MyStoreItem c where c.quantity =0"
    signature="java.util.Collection findByOutOfStock()"
    

    Abajo puedes ver un fragmento de código de estos métodos finder en la clase ItemLocalHome después de regenerar las clases EJB:

Ahora, regenera tus clases EJB y analiza las clases importantes. Todos los métodos finder están completos. Añadamos ahora algunos métodos de negocio.

. Añadir Métodos de Negocio:

  • Ahora añade un método de negocio con la siguiente firma: public ItemData getItemData() con el tipo de interface local.
    Nota:
    Ya hemos visto como añadir métodos de negocio en las páginas anteriores...

    Estos proporciona la descripción de los ítems individuales de MyStore.

  • Añade algunas sentencias de depuración y devuelve un ejemplar de ItemData:
  • Añade otro método de negocio con la siguiente firma: public void fillStock (Integer quantity) con el tipo de interface como local. Esto incrementará los ítems disponibles en MyStore después de la llegada de más ítems. Añade algunas sentencias de depuración y las siguientes líneas para completar el método:
    Integer qty = new Integer((quantity.intValue() + getQuantity().intValue()) );
    setQuantity (qty);
    

    Abajo puedes ver un fragmento del método fillStock de la clase ItemBean:

. Añadir un Método de Retrollamada:

Al contrario que en BMP (donde se generarón automáticamente) tenemos que añadir los métodos de retrollamadas que se sobreescribirán en la clase ItemCMP.

  • Primero importa el siguiente paquete:
    javax.ejb.EntityContext
  • Añade un campo para almacenar el contexto de entidad:
    protected EntityContext eContext;
  • Añade un método setEntityContext con entityContext como parámetro y asignalo a tu variable entityContext.
  • Añade un método unsetEntityContext, que ponga a null la variable entityContext.

Ahora ya están completos todos los métodos, es hora de regenerar las clases EJB y examinar la clase ItemCMP generada, que es la más interesante.

Al contrario que en nuestro bean BMP todo el comportamiento de persistencia de atributos se ha sobreescrito por métodos abstractos. Esto es porque el contenedor EJB es el responsable de mantener su persistencia.

Todos los métodos de retrollamadas que hemos implementado se sobreescribirán así:

Nota:
No hay métodos ejbFinder en esta clase como en los beans BMP, ya que todo esto lo controla el contenedor. Al igual que ya apuntamos antes, tampoco se generan clases PrimaryKey ni se necesita una clase DAO, porque todo lo controla el contenedor.

Ahora, antes de desplegar nuestro bean, echaremos un vistazo a ejb-jar.xml y jboss.xml para ver que descriptores se han generado.

Nota:
No tenemos que escribir ningún descriptor para la fuente de datos como hicimos en los beans de sesión y BMP, ya que el contenedor EJB es el responsable de esto.

Como se ve el fragmento anterior, todos los métodos abstractos se han generado como campos persistentes dento de la etiqueta <cmp-field> debido a la etiqueta @persistence-field declarada en cada método accesor. También se han generado el descriptor de la clase primaria dentro de la etiqueta <primary-key-class> y el campo de la clave primaria en la etiqueta <primarykey-field> debido a la etiqueta @field-pk declarada para los atributo(s) importantes.

Los descritores de los métodos finder se han generado junto con la consulta definida para buscar los datos como se ve abajo. Estas etiquetas finder las ha generado la etiqueta @ejb.finder declaraa a nivel de clase.

Y en el fichero jboss.xml, se han generado los siguiente descritores mediante la etiqueta @ejb.bean declarada a nivel de clase:

Se ha completado la funcionalidad del bean Item y ya está listo para desplegarlo.

. Desplegar el Bean Item:

  • Ve a Lomboz J2EE View y expande los nodos MyStore > MyStoreMgr, selecciona Jboss 3.2.1 ALL.
  • Pulsa con el botón derecho y selecciona Debug Sever en el menú desplegable.
  • Nota:
    Esto es para arrancar el servidor. Si ya está ejecutándose saltate estos pasos y ve al siguiente.
  • Ve al nodo MyStoreMgr en Lomboz J2EE View, pulsa con el botón derecho y selecciona Deploy en el menú desplegable:

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

Ahora modifiquemos StoreAccessBean para llamar a los métodos de ItemBean.

  • Añade un campo para almacenar nuestra referencia a Item (obtenida mediante JNDI):
    private ItemLocalHome itemLocalHome;
  • En el método ejbCreate almacena esta referencia en la variable itemLocalHome llamando al método estático getLocalHome de la clase ItemUtil:

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

Ahora añadiremos otro método de negocio al bean StoreAccess para llamar a los métodos de negocio de nuestro bean Item.

  • Añade un método de negocio con esta firma: public ItemData getItemData(String itemID), con el tipo de interface local. Como los managers entran en MyStore con su username, una vez autenticados serán identificados con su userid. Los managers pueden llamar a los métodos del bean Item para examinar el inventario.
  • Llama a uno de los métodos finder de Item mediante la variable que hemos creado en el método ejbCreate:
    ItemLocal item  =   itemLocalHome.findByPrimaryKey(itemID)
  • Ahora llama a un método de negocio de Item con esta referencia:
    ItemData myItem = item.getItemData() 
    
  • Añade otro método de negocio al bean StoreAccess con la firma: public java.util.ArrayList getOutOfStockItems() y con el tipo de interface como remote. Este devolverá los ítems que estén fuera de stocks en MyStore.
  • Crea dos variables de los tipos Collection y ArrayList respectivamente, ya que el método finder de Item devuelve una Collection y este método devolverá un ArrayList, después de rellenarlo con los ítems fuera de stocks de la Collection. devuelta:
    Collection items = null;
    ArrayListItemsOutOfStock = null;
    
  • Ahora llama a uno de lo métodos finder de Item con la variable que hemos creado en el método ejbCreate:
    items = itemLocalHome.findByOutOfStock()
  • Itera por la collection de ítems fuera de stock y añadelos al ArrayList:
    ItemLocal myItemLocal  = (ItemLocal) iterate.next();
    itemsOutOfStock.add(myItemLocal.getItemData());
    
  • Añade otro método de negocio a StoreAccess con la firma: public java.util.ArrayList getItemBySupplier(String supplierID), con el tipo de interface remote. Este devolverá la lista de ítems suministrados por un proveedor dado.
  • >Crea dos variables de los tipos Collection y ArrayList respectivamente, ya que el método finder de Item devuelve una Collection y este método devolverá un ArrayList, después de rellenarlo con los ítems suministrados por un proveedor particular:
    Collection suppliedItems = null;
    ArrayList itemsBySupplier = null;
    
  • Ahora llama a uno de los métodos finder de Item con la variable creada en el método ejbCreate:
    suppliedItems = itemLocalHome.findBySupplierID(supplierID)
  • Itera sobre la colección de ítems y añádelos al ArrayList:
    ItemLocal myItemsLocal  = (ItemLocal) iterate.next();
    itemsBySupplier.add(myItemsLocal.getItemData());
    

Ahora que hemos añadido a StoreAccess todos los métodos necesarios para acceder a los métodos de negocio de Item, lo único que nos queda son los descriptores de despliegue requeridos para enlazar/referenciar StoreAccess y Item. Por eso añadiremos estás dos etiquetas:

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

    Esta etiqueta generará los descriptores de despliegue en ejb-jar.xml, ya que StoreAccessBean tiene que saber a qué bean se está referenciando, cuál es su view-type y su ref-name. Esto generará los siguientes descriptores de despliegue:

  • Añade una segunda etiqueta a StoreAccess a nivel de clase:
    @jboss.ejb-ref-jndi ref-name="ItemLocal"
    jndi-name="ItemLocal"
    

    Esta etiqueta generará los descriptores de despliegue en jboss.xml, ya que el servidor de aplicaciones tiene que saber qué nombre JNDI tiene el bean que se ha registrado. Esto generará estos descriptores de despliegue:

    Nota:
    ref-name y jndi-name se utilizan para beans locales (en la misma JVM).
Nota:
Podemos ver en los descriptores de despliegue generados por la etiqueta @jboss, que para los tipos de vista 'local' genera descriptores de despliegue incorrectos, como explicamos en páginas anteriores. Por eso, cada vez que utilices esta etiqueta tienes que cambiar el <ejb-ref> por <ejb-local-ref> antes del despliegue.
Cuidado: tienes que hacer esto manualmente cada vez que regeneres tus clases EJB, ya que jboss.xml se sobreescribirá en cada regeneración.

Tras estos cambios nuestro bean Item ya está completo, ya puedes desplegarlo de nuevo, desde Lomboz J2EE View. La consola te indicará el estado del despliegue.

Una vez que el bean se ha desplegado con éxito, crea un test de cliente que llame al método loginUser del bean StoreAccess, a getCustomerData del bean Customer, a getManagerData del bean Manager y a getOutOfStockItems del bean Item.

. Crear tu Test de Cliente:

  • Ve al nodo del proyecto MytStore selecciona el nodo src y expándelo; selecciona el paquete au.com.tusc.client y pulsa el botón derecho.
  • Selecciona New en el menú y luego Lomboz EJB Test Client Wizard.
  • Pon au.com.tusc.client como nombre de paquete, SessionCMPClient como nombre de sesión, au.com.tusc.session.StoreAccessHome como EJB Home y au.com.tusc.session.StoreAccess como EJB Interface.

    Esto generará los métodos necesarios en tu clase SessionCMPClient y sólo tendrás que llamar a loginUser, getCustomerData, getManagerData (el bean Manager se desarrolló como parte del ejercicio de la página anterior) y a getOutOfStockItems.

  • Ahora, el último paso para escribir el código de tu cliente. Para acceder a los ítems fuera de stock necesitaremos un Iterator y un ArrayList. Declara dos variables de estos tipos, e importa los paquetes necesarios(java.util.ArrayList y java.util.Iterator).
    Iterator itemsIterator = null;
    ArrayList items = null;
    
  • Y ahora añade esta líneas de código para llamar a los métodos mencionados arriba:
    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 );
    String mgrID =   myBean.loginUser("RUSTY","PASSWD");
    System.out.println("Reply from Server: Your mgrid is " + mgrID );
    ManagerData md = myBean.getManagerData(mgrID);                  
    System.out.println ("Rusty your details with MyStore are  " + md );                     
    System.out.println("Manager Request : List items out of stock ");
                                                    
    items = myBean.getOutOfStockItems();
    itemsIterator = items.iterator();
    System.out.println("List Of Out Of stock Items ");                      
    
    while ( itemsIterator.hasNext() ) {                     
       ItemData itemData= ( ItemData ) itemsIterator.next();
       System.out.println ("Item Data " + itemData );
    }
    

. Probar tu Cliente:

  • Ahora, para poder probar tu cliente, selecciona el nodo SessionCMPClient.
  • Ve al menú de la parte superior y selecciona el icono con el 'hombre corriendo'.
  • En él selecciona Run as y elige Java Application, como se ve en la siguiente figura:

Ahora en tu consola, deberías obtener como repuestas CALCULATOR y CLOCK, exactamente igual que en esta imagen:

. Ejercicio:

Aquí tienes un ejercicio para tí. Para seguir más allá, debes implementar Supplier como un bean de entidad CMP. Aquí tienes la lista de tareas:

  1. Crea un bean CMP llamado Supplier en el paquete au.com.tusc.cmp.
  2. Implementa el método ejbCreate, pasando todos los atributos como argumentos y asignando esos atributos utilizando métodos mutadores.
  3. Añade un método finder llamado findUserID con la consulta:
    query "SELECT OBJECT(b) FROM MyStoreSupplier as b where b.userID = ?1"

    y la firma:
    au.com.tusc.cmp.SupplierLocal findUserID(java.lang.String userID)
    Nota:
    La firma del método es find<cmp attribute> en lugar de findByPrimaryKey, porque los métodos finder de atributos que no son claves utilizan esta covención. De acuerdo al tipo de retorno para los métodos finder será Collection o <entity type>, según se especifica en la especificación EJB, secciones 10.5.6 y 10.5.2, respectivamente.
  4. Añade un método de negocio para obtener los detalles del proveedor con la firma:
    public SupplierData getSupplierData()
  5. Añade un método de negocio para obtener los ítems de varios proveedores con la firma:
    public void requestItem(String itemID, Integer quantity)
  6. Añade métodos de retrollamada, necesarios para seleccionar/deseleccionar el contexto del bean con la firma:
    public void setEntityContext(EntityContext ctx)
    public void unsetEntityContext()
    
  7. Despliega el bean Supplier.
  8. Añade un campo al bean StoreAcess para almacenar su referencia:
    private SupplierLocalHome supplierLocalHome
  9. En el método ejbCreate de StoreAccess almacena una referencia en la variable supplierLocalHome llamando al método estático getLocalHome de supplierUtil.
  10. Añade un método de negocio al bean StoreAccess con la firma:
    public ItemData getItemData(String itemID)
  11. Añade las siguientes etiquetas a nivel de clase para el enlace/referencia en el despliegue:
    1. @ejb.ejb-ref ejb-name="Supplier"
        view-type="local"
        ref-name="SupplierLocal"
     
    2. @jboss.ejb-ref-jndi ref-name="SupplierLocal"
        jndi-name="SupplierLocal" 
    
  12. Prueba tu Bean Supplier ejecutando tu test de cliente creado para Item llamado SessionCMPClient.
Nota:
Todos estos pasos ya los has realizado para implementar el bean Item. Es necesario que implementes este bean porque lo utilizaremos en las páginas siguientes:
En el caso de que tengas dificultades, aquí te proporcionamos las clases para que las descargues:
Publicado por:
Administrador
Recomendar
a un amigo
Compartir
en redes
 
Comentarios
 
BBDD
Entornos de desarrollo
Entretenimiento
Herramientas
Internet
Lenguajes de script
Lenguajes imperativos
Lenguajes orientados a objeto
Otros lenguajes
Plataformas
Teoría
Varios
Copyright © 1998-2011 Programación en Castellano. Todos los derechos reservados
Datos legales | Politica de privacidad | Contacte con nosotros | Publicidad

Diseño web y desarrollo web. Un proyecto de los hermanos Carrero.

Red internet:
Juegos gratis | Servidores dedicados
Más internet: Password | Directorio de weblogs | Favicon