Вы находитесь на странице: 1из 51

Capa de presentacin

Capa de Negocio

Capa de Negocio

Se ha elegido la versin de EJB 3.0 debido a las siguientes caractersticas:


Tiene una API de persistencia simplificada Anotaciones de metadatos Lenguaje de consultas mejorado Uso de defaulting Inyeccin de dependencias Simplificacin de los beans de sesin

La principal diferencia entre EJB3 y EJB2.x es el manejo de la persistencia. Antes de EJB 3 exista un mapeo objeto/relacional limitado entre beans de entidad y tablas relacionales. No era posible la herencia y el polimorfismo. En EJB 3 un bean de entidad es un objeto Java verdadero. La otra principal innovacin de EJB 3 es la introduccin de anotaciones de metadatos. Las anotaciones de metadatos fueron introducidas en Java 5, de forma que cuando se desarrollen EJB 3 se utilizar esa versin de Java o una posterior. Las anotaciones de metadatos podrn utilizarse como una alternativa a los descriptores de deployment XML, para configurar componentes EJB y especificar mapeos objeto/relacional con entidades. Sin embargo, los descriptores de deployment pueden seguir utilizndose.

El EJB Query Language (EJBQL) disponible en versiones anteriores fue ms limitado en comparacin con JPQL de JPA. En particular JPQL proporciona las siguientes mejoras:
Proyecciones Clusulas GROUP BY y HAVING Joins Subqueries Queries Dinmicas Queries con parmetros Actualizacin en lote y operaciones delete.

El uso extensivo de defaults es hecho en EJB 3. Por ejemplo, la mayora de las anotaciones de metadatos no requieren que le sean especificados elementos o parmetros, el comportamiento esperado usualmente es el comn por default. Los elementos anotacin son usualmente necesarios solo cuando queremos configurar comportamientos excepcionales.

La inyeccin de dependencias que caracteriz al framework Spring, ha sido introducido a EJB 3 como una alternativa a JNDI para localizar recursos administrados por el contenedor. Los bean de sesin han sido simplificados. Ya no necesitamos especificar componentes e interfaces home. Adems la clase bean de sesin ya no tiene que implementar muchas interfaces callback an cuando estas no son requeridas por la aplicacin. En EJB3 estos mtodos de callback de ciclo de vida son implementados por los beans de sesin slo cuando se requieren.

Anotaciones
La opcin de anotaciones es una de las caractersticas ms importantes que distingue a EJB 3 de versiones anteriores. Las anotaciones de metadatos fueron introducidas en Java SE 5. Por esta razn EJB 3 debe usarse en conjuncin con Java SE 5 o posterior. En EJB 2.x en vez de anotaciones se utilizaban descriptores de deployment. Como su nombre lo sugiere, los descriptores de deployment son ledos por el servidor de aplicaciones cuando el EJB es deployado. En las notas se presenta un descriptor de deployment ejemplo junto con una interface y bean de sesin.

Las anotaciones son por mucho ms fciles de usar que los descriptores de deployment. Los descriptores de deployment suelen ser verbosos, no muy legibles por humanos y tienden a errores cuando se editan de forma manual. Cualquier archivo descriptor de deployment no trivial necesita una herramienta para lectura y escritura. El uso de anotaciones significa recompilar un bean cuando slo queremos cambiar un aspecto de deployment; modificar un descriptor de deployment no requiere recompilacin. Sin embargo, las anotaciones son opcionales en EJB 3, an se puede usar descriptores de deployment si lo deseamos. Adems los descriptores de deployment se pueden mezclar con las anotaciones en EJB3. Los descriptores de deployment siempre sobrescriben a las anotaciones.

Un enfoque podra ser usar anotaciones para aquellos aspectos de un EJB que raramente van a cambiar entre deployments.

Ciclo de vida de un bean de sesin statefull


Es importante subrayar que el ciclo de vida de un bean de sesin sin estado es controlado por el contenedor y no por la aplicacin. El siguiente diagrama muestra el ciclo de vida de un bean de sesin sin estado:

El estado inicial de un bean de sesin es el estado no-existe. Este sera el caso antes de que un contenedor inicie, por ejemplo. El sig estado es el method-ready pool. Cuando el contenedor inicia, tpicamente crea un nmero de instancias de bean de sesin sin estado en el method-ready pool. Sin embargo, el contenedor puede decidir en cualquier momento crear tales instancias. Con el fin de crear tal instancia en el method-ready pool, el contenedor ejecuta los siguientes pasos:

1. 2. 3.

4.

El bean es instanciado. El contenedor inyecta el SessionContext del bean, si aplica. El SessionContext es usado por un bean para consultarle al contenedor sobre el estatus o contexto del bean. El contenedor ejecuta cualquier otra inyeccin de dependencias que es especificada en el metadato del bean. El contenedor entonces invoca un mtodo callback PostConstruct, si hay uno presente en el bean. El mtodo PostConstruct sera usado para inicializar cualquier recurso utilizado por el bean. Por ejemplo, el bean de sesin puede hacer uso de una queue JMS para enviar mensajes. La queue de conexin usada por JMS podra ser inicializada en el mtodo PostConstruct. Un mtodo PostConstruct es llamado solo una vez en la vida de una instancia, cuando se transita de un estado no-existe al method-ready pool

El contenedor luego llama un mtodo de negocio en el bean. Cada llamada al mtodo de negocio podra originarse desde un cliente diferente. Inversamente, cuando un cliente invoca un mtodo de negocio en un bean de sesin sin estado cualquier instancia en el method ready pool puede ser elegido por el contenedor para ejecutar el mtodo. Despus de que un mtodo de negocio ha sido invicado, el contenedor puede decidir destruir la instancia del bean (tpicamente si el contenedor decide que hay demasiadas instancias del method-ready pool) o reutilizar la instancia en nombre de cualquier cliente que invoque su mtodo de negocio.

Cuando el contenedor decide destruir la instancia primero invoca el mtodo callaback PreDestroy si hay uno presente en el bean. El mtodo PreDestroy sera usado para poner en orden actividades, tal como cerrar conexiones que pudieron haber sido abiertas en el mtodo PostConstruct. Un mtodo PreDestroy es llamado slo una vez en la vida de una instancia, cuando est por transicionar al estado no-existe. Estas caractersticas de agrupamiento de instancias y comparticin de instancias significa que los beans de sesin sin estado se escalan bien ante un nmero grande de clientes.

Ciclo de vida de un bean de sesin stateful


El siguiente diagrama muestra el ciclo de vida de un bean de sesin sin estado

El ciclo de vida de un bean de sesin stateful es diferente del de un bean de sesin sin estado en muchas cosas. No hay agrupamiento de instancias de bean idnticos, debido a que cada instancia sirve a un solo cliente. Un bean de sesin stateful transita de un estado no-existe a un estado method-ready tan pronto como un cliente ejecuta una bsqueda de la interfaz de negocio o una inyeccin de dependencia de un bean. As que este paso es instanciado por el cliente y no por el contenedor. Una vez que un bean de sesin stateful est en un estado method-ready, el contenedor ejecuta los mismos pasos que con un method-ready de un bean de sesin sin estado.

1. El bean es instanciado. 2. El contenedor inyecta el SessionContext del bean, si aplica. 3. El contenedor ejecuta cualquier otra inyeccin de dependencias que es especificada en el metadato del bean. 4. El contenedor entonces invoca un mtodo callback PostConstruct, si hay uno presente en el bean. El contenedor luego llama un mtodo de negocio en el bean

Recalcamos que un bean de sesin puede involucrar considerable tiempo ocioso si un cliente decide esperar, o ejecutar otras actividades, entre llamadas a mtodos. La cach del contenedor podra llegar a estar completa de instancias de beans de sesin stateful. Para limitar tales instancias, el contenedor puede cambiar estos de la cach hacia afuera del disco u otro almacenamiento. Este proceso es llamado passivation e involucra serializacin de la instancia del bean. Cuando el cliente decide invocar un mtodo en el bean pasivado, el contenedor deserializa el estado guardado e invoca el mtodo solicitado. Este proceso es conocido como activation. Nota que el mtodo puede no estar en la instancia del bean original, pero esto es seguro, de forma en que en la activacin restauramos el estado que fue guardado en la activacin.

El algoritmo de pasivacin es dependiente del contenedor, y tpicamente depende de factores como el mximo nmero de beans que pueden ser contenidos en la cach del contenedor, el mximo tiempo ocioso del bean, y la poltica de seleccin de vctima del contenedor. La poltica de seleccin de vctima de glassfish tiene las siguientes opciones: Menos Recientemente Usado(LRU), No Recientemente Usado(NRU), y Primero en Entrar Primero en Salir(FIFO). Todos estos factores pueden ser configurados por el administrador del contenedor.

El bean puede proporcionar un mtodo callback @Prepassivate, el cual es ejecuta inmediatamente antes de la pasivacin, y un mtodo @PostActivate, el cual es ejecutado inmediatamente despus de la activacin. Un bean de sesin stateful puede contener recursos abiertos como sockets abiertos, conexiones JMS o a base de datos, que no pueden ser manejadas por el contenedor durante la pasivacin. En estos casos el recurso ser cerrado en el mtodo @Prepassivate y reabierto en el mtodo @PostActivate.

Un bean puede moverse desde un estado method-ready a un estado no-existe si un mtodo anotado @Remove es invocado. Un bean puede hacer esto tambin si el periodo de timeout configurado del contenedor ha sido alcanzado. En tal caso, un mtodo anotado @PreDestroy es invocado antes. Un bean pasivado tambin puede moverse a un estado no existe si un periodo de timeout ha sido alcanzado. Nota en este caso que cualquier mtodo anotado @PreDestroy no ser invocado

Interfaces locales
Tras las escenas, una interfaz remota utiliza el protocolo RMI-IIOP para operaciones de red. Este protocolo estipula que los argumentos del mtodo son pasados por valor y no por referencia. Pasar por valor significa que un objeto pasado por el cliente al bean remoto, o viceversa, primero es serializado, luego pasado sobre la red, y luego deserializado. Todo esto tiene un impacto en trminos de performance. An si nuestro cliente es un bean de sesin que invoca a otro en el mismo contenedor hay una sobrecarga en el performance si usamos una interfaz remota debido a que se produce una serializacin y deserializacin. Por esta razn la tecnologa EJB proporciona una opcin de interfaz local para beans de sesin. Los argumentos de los mtodos son pasados por referencia y no por valor de forma que mejoran el performance. Para ilustrar esto creemos un bean de sesin que ser invocado y ejecutado en el mismo contenedor EJB, como nuestro TimeServiceBean original. Este bean invocado nicamente retornar Que tengas un buen da, primero definimos la interfaz del bean BuenDiaService.

La definicin de interface anterior se prefij con la anotacin @Locale. Esto indica al contenedor EJB que este bean slo puede ser invocado por un cliente local que corre en el mismo contenedor. La interfaz consiste de tan slo la definicin de un mtodo, getMessage(). A continuacin veremos la implementacion del bean BuenDiaServiceBean:
package ejb30.session; import java.util.*; import javax.ejb.Stateless; @Stateless public class NiceDayServiceBean implements NiceDayService { public String getMessage() { return " Que tengas un Buen Dia"; } } Todo esto es correcto, notamos que el bean de sesin es sin estado y el mtodo getMessage() retorna la cadena Que tengas un buen da.

Vamos a ver cmo podramos modificar TimeServiceBean para invocar BuenDiaService. El TimeServiceBean agregar el mensaje BuenDiaService a la hora actual. Aqu est el cdigo modificado para TimeServiceBean:
package ejb30.session; import java.util.*; import javax.ejb.Stateless; import javax.ejb.EJB; @Stateless public class TimeServiceBean implements TimeService { private @EJB NiceDayService niceDay; public String getTime() { Formatter fmt = new Formatter(); Calendar cal = Calendar.getInstance(); fmt.format("%tr", cal); return fmt.toString() + niceDay.getMessage(); }

Usamos la anotacin @EJB para instruir al contenedor que busque el bean BuenDiaService, e inyectar una referencia al bean en el campo niceDay. Recordamos que este es un ejemplo de inyeccin de campo. Luego podemos invocar el mtodo niceDay.getMessage(). Una alternativa a la inyeccin de campo es la inyeccin de setter. En este caso es anotado un mtodo ms que un campo. La siguiente versin de TimeServiceBean usa inyeccin de setter. Anotando el mtodo setNiceDay() con la anotacin @EJB estamos instruyendo al contenedor que busque el bean BuenDiaService, luego invoca al mtodo setNiceDay() pasndole la referencia del bean BuenDiaService como parmetro a setNiceDay()

ENTIDADES
Las entidades son clases que necesitan ser persistidas, generalmente en una base de datos relacional. Veremos los siguientes temas:
Entidades EJB 3 API de persistencia Java Mapear una entidad a una tabla de base de datos Metadatos defaults Introduccin al entity manager Empaquetar y deployar entidades Generar llaves primarias Sobrescribir metadatos defaults

ENTIDADES
Las entidades son clases que necesitan ser persistidas; su estado es almacenado fuera de la aplicacin, tpicamente en una base de datos relacional. A diferencia de los beans de sesin, las entidades las entidades no tienen lgica de negocio diferente que la validacin. De igual forma que el almacenamiento de tales entidades, queremos consultar, actualizar, y eliminarlas. La especificacin EJB 3 reconoce que muchas aplicaciones tienen las necesidades de persistencia anteriores sin requerir los servicios (seguridad, transacciones) de un contenedor EJB de servidor de aplicacin. Consecuentemente los aspectos de persistencia de EJB3 han sido empaquetados como una especificacin separada la Java Persistece API (JPA). JPA no asume que tenemos un contenedor y podemos utilizarla an en una aplicacin Java SE. La mayora de los ejemplos asumen que el motor de persistencia existe sin un contenedor EJB 3 como Glass Fish o Jboss.

ENTIDADES
Productos de mapeo objeto/relacional exitosos como un Hibernate open source, o propietarios como Oracle Toplink han implementado estas tecnologas de persistencia desde hace aos. Los creadores de Oracle Toplink y Hibernate han infludo en el desarrollo de la especificacin JPA. JPA puede considerarse como un alto nivel de abstraccin, situndose en lo alto de JDBC. Bajo la cubierta, el engine de persistencia convierte sentencias JPA en sentencias JDBC de bajo nivel.

ENTIDADES
Entidades EJB 3 En JPA cualquier clase o POJO puede ser convertido a JPA con pocas modificaciones. El siguiente cdigo muestra una entidad Cliente.java con atributos id, que es nico para una instancia de un cliente, y nombre y apellido.

ENTIDADES
La clase sigue las reglas de JavaBean usuales. Las variables de instancia son no pblicas y son accesadas por clientes a travs de mtodos de acceso getters y setters de forma apropiada. Solo un par de anotaciones han sido agregadas para distinguir esta entidad de un POJO. Las anotaciones especifican metadatos de entidad. No hay una parte intrnseca de una entidad, pero describe como es persistida una entidad, o cmo una entidad est relacionada con otras entidades. La anotacin @Entity indica al engine de persistencia que la clase anotada, en este caso Cliente, es una entidad. La anotacin es inmediatamente colocada antes de la definicipon de la clase y es un ejemplo de anotacin a nivel de clase. Tambin podemos tener anotaciones basadas en propiedades y basadas en campos, como podemos ver.

ENTIDADES
La anotacin @Id especifica la llave primaria de la entidad. El atributo id es una llave primaria candidata. Nota que se ha colocado la anotacin inmediatamente antes del mtodo getter correspondiente, getId(). Este es un ejemplo de anotacin basada en propiedad. Una anotacin basada en propiedad debe ser colocada inmediatamente antes del mtodo setter correspondiente, y no al mtodo getter. Donde las anotaciones basadas en propiedad son utilizadas, el engine de persistencia usa los mtodos getters y setters para accesar y asignar el estado de la entidad. Una alternativa a las anotaciones basadas en propiedad son las anotaciones basadas en campos. Nota que todas las anotaciones en una entidad, diferentes que las anotaciones a nivel de clase, deben ser todas basadas en propiedad o todas basadas en campo. Nuestra entidad Cliente tambin implementa la interfaz Serializable. Esto no es esencial, pero es una buena prctica, debido a que la entidad cliente tiene el potencial de llegar a ser una entidad suelta (detached). Las entidades sueltas deben implementar la interfaz Serializable.

ENTIDADES
Comparacin con los beans de entidades EJB 2.x
Una entidad EJB 3 es un POJO y no un componente, de forma que se es referido como una entidad y no como un bean de entidad. En EJB 2.x la construccin correspondiente es un componente bean de entidad con los mismos artefactos que un bean de sesin, a saber, un archivo descriptor de deployment, una interfaz local o remota, una interfaz home o localhome, y la misma clase del bean. La interfaz local o remota contiene definiciones de mtodos setter y getter. La interfaz local o home contiene definiciones para los mtodos create() y findByPrimaryKey(), y opcionalmente otras definiciones de mtodos de bsqueda. Como con los beans de sesin, la clase bean de entidad contiene mtodos callback como ejbCreate(), ejbLoad(), ejbRemove(), ejbActivate(), ejbPassivate(), y setEntityContext().

ENTIDADES
La entidad EJB 3 siendo un POJO, puede correr fuera de un contenedor, sus clientes siempre son locales a la JVM. El bean de entidad EJB 2.x es un objeto distribuido que necesita un contenedor para correr, pero puede tener clientes desde fuera de su JVM. Consecuentemente, las entidades EJB 3 son ms reutilizables y ms fciles de probar que los beans de entidad EJB 2.x. En EJB 2.x necesitamos decidir si los aspectos de persistencia de un bean de entidad son manejados por el contenedor (Container Managed Persistence, CMP) o por la aplicacin (Application Managed Persistence, BMP). En el caso de CMP, el bean de entidad es definido como una clase abstracta con definiciones de mtodos getters y setters abstractos. En el deployment el contenedor crea una implementacin concreta de esta clase de bean de entidad abstracta. En el caso de BMP, el bean de entidad es definido como una clase, los mtodos getters y setters necesitan ser codificados. Adems del ejbCreate(), ejbLoad(), ejbStore(), ejbFIndByPrimaryKey(), y cualquier otro mtodo de bsqueda, necesita ser codificado usando JDBC.

ENTIDADES
Mapeando una entidad a una tabla de base de datos
Podemos mapear entidades en casi cualquier base de datos relacional. Glassfish incluye una base de datos relacional Derby embebida. Si queremos que Glasfish accese a otra base de datos relacional , dgase Oracle, entonces necesitamos usar la consola de administracin Glasfish para configurar una fuente de datos Oracle. Tambin necesitamos referirnos a esta base de datos Oracle en el archivo persistence.xml. Estos pasos no se requieren si vamos a usar la fuente de datos Derby default. En todos los ejemplo usaremos la base de datos Derby. EJB 3 hace fuerte uso de defaulting para describir metadatos de entidades. En esta seccin describiremos algunos de estos defaults. Primero, por default, el engine de persistencia mapea el nombre de la entidad a un nombre de tabla relacional. As, nuestro nombre de la tabla es CLIENTE. Si queremos mapear la entidad CLIENTE a otra tabla necesitaremos usar la anotacin @Table.

ENTIDADES
Por default los nombres de propiedades o campos son mapeados a nombres de columnas. As ID, NOMBRE, APELLIDO, son los nombres de columnas correspondientes a los atributos de la entidad id, nombre y apellido. Si queremos cambiar este comportamiento default, necesitaremos usar la anotacin @Column. Las reglas JDBC son usadas para mapear primitivos Java a tipos de datos relacionales. De esta forma, una String ser mapeada a VARCHAR para una base de datos Derby y VARCHAR2 para una base de datos Oracle. Un int ser mapeado a INTEGER para una base de datos Derby y NUMBER para una base de datos ORACLE. El tamao de una columna mapeada de una String por default es 255, VARCHAR(255) para Derby, y VARCHAR2(255) para Oracle. SI queremos cambiar este tamao de columna, necesitamos usar el elemento length de la anotacin @Column.

ENTIDADES
Introduccin al EntityManager
Usaremos un bean de sesin sin estado remoto para operaciones de negocio en la entidad Cliente. Llamaremos a nuestra interface del bean de sesin BankService. Mas adelante agregaremos mas entidades y operaciones de negocio que tpicamente son usadas por una aplicacin bancaria. En esta etapa nuestra aplicacin bancaria trata con una entidad Cliente, y mtodos de negocio addCliente() y findCliente(), que respectivamente agregan un cliente a la base de datos y retoman una entidad cliente dados los identificadores de los clientes. La interface se lista en las notas. As mismo despus de la interfaz se muestra la implementacin del bean de sesin, BankServiceBean.

ENTIDADES
El EntityManager es un servicio provisto por el engine de persistencia que proporciona mtodos para persistir, encontrar, consultar, remover, y actualizar entidades. El conjunto de instancias de la entidad manejada es conocido como contexto de persistencia. Es importante subrayar que un contexto de persistencia est asociado con un conjunto administrado de instancias u objetos de entidad. Si tenemos, por decir, 10 clientes accesando el bean, tendremos 10 contextos de persistencia. Asociado con un EntityManager es una unidad de persistencia que especifica informacin de configuracin. La sentencia define:
@PersistenceContext(unitName="BankService") private EntityManager em;

define una instancia EntityManager em con un contexto de persistencia asociado llamado BankService. La configuracin de la actual unidad de persistencia est especificada en el archivo persistence.xml, que veremos pronto.

ENTIDADES
Actualmente, tras escenas, la anotacin @PersistenceContext causa que el contenedor:
Use el EntityManagerFactory para crear una instancia del EntityManager Enlace la instancia del EntityManager a la unidad de persistencia BankService. Inyecte la instancia EntityManager en el campo em.

Ahora vamos a ver el mtodo addCliente(). Primero la sentencia


Cliente cust = new Cliente();

crea, como se espera, una instancia de la entidad Cliente. Sin embargo, en esta etapa la instancia de la entidad no est administrada. La instancia an no est asociada con un contexto de persistencia. Las instancias de la entidad administradas tambin se les refiere como instancias ligadas y las instancias no administradas como instancias sueltas. Las siguientes sentencias invocan los mtodos setter de Cliente en la forma usual. La sentencia
em.persist(cust);

invoca al mtodo EntityManager.persist().

ENTIDADES

ENTIDADES

ENTIDADES

ENTIDADES

ENTIDADES

ENTIDADES

ENTIDADES

ENTIDADES

ENTIDADES

ENTIDADES

Вам также может понравиться