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.
- 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 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.
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:- Expande el nodo MyStoreMgr en el proyecto MyStore en el Package Explorer.
- Pulsa con el bot�n derecho y aparecer� un men� desplegable.
- 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.
- 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:
- @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().
- @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.
- @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.
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.
�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:
- Crea un bean BMP llamado Manager en el paquete au.com.tusc.bmp.
- Crea una clase DAO llamada ManagerDAOImpl en el paquete au.com.tusc.dao.
- A�ade todos los atributos/propiedades de ManagerBean, a�ade los m�todos accesores/mutadores para cada atributo.
- A�ade un m�todo find llamado ejbFindByPrimaryKey con la firma:
ejbFindByPrimaryKey (MangerPK pk) throws FinderException.
- A�ade un m�todo find llamado ejbFindByUserID con la firma:
public MangerPK ejbFindByUserID (String userID) throws FinderException
- A�ade un m�todo de negocio llamado getManagerData con la firma:
public ManagerData getManagerData()
- Implementa los m�todos en la clase ManagerDAOImpl. El string de b�squeda requerido por el API JNDI es "java:comp/env/jdbc/DefaultDS".
- Despliega el Bean.
- A�ade un campo al bean StoreAccess para almacenar la referencia despu�s de buscar el manager en JNDI.
private ManagerLocalHome manager LocalHome;
- En el m�todo ejbCreate del bean StoreAccess almacena la referencia a la variable managerLocalHome llamando al m�todo est�tico getLocalHome de ManagerUtil.
- A�ade un m�todo de negocio al bean StoreAccess:
public MangerData getManagerData(String userID)
- 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"
- 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:
Nota:
|