Desarrollo de un mecanismo para el manejo de la persistencia transparente de objetos en Java
Texto completo
(2) Tabla de Contenido 1 2. 3. 4. 5. 6. 7. 8. Introducción ........................................................................................................... 4 Estado del arte........................................................................................................ 7 2.1 JDO ................................................................................................................ 8 2.2 EJB............................................................................................................... 11 2.3 Uso de JDO en J2EE..................................................................................... 12 2.4 JDO vs. Entity Beans .................................................................................... 13 2.5 ODMG ......................................................................................................... 16 2.6 Resumen y conclusiones del estado del arte .................................................. 18 Análisis de JDO como mecanismo de persistencia................................................ 19 3.1 Características principales de la especificación JDO ..................................... 19 3.2 Caso de estudio............................................................................................. 20 3.3 Análisis de la utilización de JDO .................................................................. 22 3.4 Conclusiones ................................................................................................ 25 Diseño del modelo de persistencia para PSeneca .................................................. 27 4.1 Alcance ........................................................................................................ 27 4.2 Diseño Global............................................................................................... 28 4.3 Ciclo de vida de un objeto persistente ........................................................... 32 4.4 Declaración de la persistencia ....................................................................... 34 4.5 Diseño Detallado .......................................................................................... 35 Diseño Detallado de la implementación de PSeneca ............................................. 45 5.1 Paquete co.edu.uniandes.ccdl........................................................................ 45 5.2 Paquete co.edu.uniandes.ccdl.base ................................................................ 45 5.3 Paquete co.edu.uniandes.ccdl.implementation............................................... 51 5.4 Paquete co.edu.uniandes.ccdl.metadata......................................................... 60 5.5 Paquete co.edu.uniandes.ccdl.query .............................................................. 69 5.6 Paquete co.edu.uniandes.adapter................................................................... 70 5.7 Paquete co.edu.uniandes.adapter.rdbms ........................................................ 70 5.8 Paquete co.edu.uniandes.adapter.rdbms.jdoxml ............................................ 71 5.9 Paquete co.edu.uniandes.adapter.rdbms.metadata ......................................... 71 5.10 Paquete co.edu.uniandes.adapter.rdbms.query............................................... 78 5.11 Paquete co.edu.uniandes.adapter.rdbms.database .......................................... 82 Lenguaje de Consulta SenecaQL .......................................................................... 86 6.1 Definición del lenguaje ................................................................................. 86 6.2 Funcionalidad Implementada del lenguaje de consulta .................................. 87 6.3 Definición de clases utilizadas para crear consultas asociativas..................... 92 Caso de Estudio.................................................................................................... 97 7.1 Descripción de la aplicación ......................................................................... 97 7.2 Requerimientos Funcionales ......................................................................... 97 7.3 Diseño .......................................................................................................... 98 7.4 Definición de la persistencia ....................................................................... 113 Análisis de Resultados........................................................................................ 116 8.1 Comparación de PSeneca con otras alternativas de persistencia .................. 116 8.2 Evaluación de la implementación de PSeneca ............................................. 122. 2.
(3) 9 Conclusiones ...................................................................................................... 127 Referencias .................................................................................................................... 129. 3.
(4) 1. Introducción. El diseño de una aplicación orientada a objetos debe tener como contexto el mecanismo y la tecnología de persistencia que se elija para su implementación. La elección de la tecnología dependerá principalmente de los requerimientos técnicos que se le impongan a la aplicación, y esta tecnología impactará el diseño de la aplicación en la medida que implique la creación y adición al modelo de nuevas clases para ajustarse y hacer uso de dicha tecnología. En el caso de Java existen diferentes mecanismos o API’s que pueden emplearse para la construcción de la persistencia, los cuales son validos para ciertos tipos de escenarios. Entre estos se encuentran la Serialización, que es viable para aplicaciones con poco volumen de datos, para las cuales una implementación en archivos es suficiente. Para aplicaciones con mayores volúmenes de datos y con requerimientos típicos de una aplicación OLTP se hace necesario el empleo de tecnologías como las de bases de datos, y junto con estas el uso de algún API que permita su comunicación y uso desde la capa del negocio de la aplicación. Las opciones para Java en este caso incluyen JDBC, SQLJ y los Entity Beans con su persistencia manejada por el contenedor (CMP) o por el Bean (BMP), todas las cuales son validas para el acceso a bases de datos relacionales. Finalmente existe la opción de JDO, que provee un API para el acceso transparente y ortogonal a cualquier tecnología de persistencia. Cada uno de estos mecanismos de acceso a datos tiene sus ventajas, desventajas y limitaciones, así como impactan, en diversos grados, la aplicación en cuanto a los siguientes factores: Estructura de la aplicación: La complejidad, transparencia y cohesión del modelo de objetos que se desarrolla para implementar la lógica del negocio y para acceder a los datos. Acoplamiento entre las capas de negocio y de datos: El nivel de conocimiento requerido por los diseñadores y desarrolladores de la capa del negocio de la estructura de la capa de datos. Facilidad de desarrollo: La cantidad y complejidad del código implementado con el fin de utilizar estas tecnologías. Flexibilidad: Las posibilidades que obtiene la aplicación en términos de almacenamiento y recuperación de datos. Desempeño: La escalabilidad y rendimiento del sistema. Evolución: El mantenimiento de la aplicación. Portabilidad: El acoplamiento con la tecnología de persistencia elegida.. 4.
(5) Las tecnologías mencionadas anteriormente ofrecen soluciones que en mayor o menor forma favorecen el desarrollo de algunos de estos aspectos mientras presentan limitaciones en su resolución de los demás. Además de la tecnología, y en ocasiones relacionada con esta, se encuentran las consideraciones de diseño que se deben tener con el fin de producir una aplicación que satisfaga estos aspectos a la luz de los requerimientos funcionales y técnicos impuestos sobre el sistema. La Universidad de los Andes ha propuesto una alternativa de solución al problema de persistencia antes mencionado (Abásolo, 2003). La alternativa consiste en una Plataforma de contenedores de componentes para el manejo de objetos persistentes con transparencia a la heterogeneidad y distribución de los datos, la cual ha sido denominada PSeneca. Su objetivo principal es “desarrollar un modelo extendido de objetos que permita expresar, bajo un solo paradigma, tanto la lógica del negocio de la aplicación como los aspectos relacionados con la persistencia, transaccionalidad y el acceso asociativo a los datos” (Abásolo, 2003). Su arquitectura es la siguiente: Contenedor de componentes de presentación. Contenedor de componentes de presentación. Contenedor de Componentes de lógica de negocio. Contenedor de componentes de coordinación global. Contenedor de componentes de datos locales. Contenedor de componentes de datos locales. Contenedor de componentes de datos locales. Contenedor de componentes de datos locales. Adaptador. Adaptador. Adaptador. Adaptador. Fuente de datos. Fuente de datos. Fuente de datos. Fuente de datos. Figura 1. Arquitectura Global de PSeneca. Fuente: Abásolo, 2003.. El primer nivel corresponde a la Capa de interfaz o de interacción con el cliente. Este nivel hace uso de los servicios ofrecidos por las clases de control, ubicadas dentro de un 5.
(6) Contenedor de Componentes de Lógica del Negocio (CCLN). Estas clases se comunican a su vez con el Contenedor de Componentes de Coordinación Global de Datos (CCCGD), quien es el encargado de brindar la transparencia a la distribución de los datos, de exportar los objetos de los contenedores locales y de redireccionar los requerimientos provenientes de las clases de control a los objetos de entidad de las capas inferiores. Cada uno de estos objetos de entidad son locales a una fuente de datos, y son mantenidos y administrados por un Contenedor de Componentes de Datos Locales (CCDL), quien se encargada de su persistencia y recuperación de manera independiente a su fuente de datos. El CCDL además exporta la parte del modelo de objetos que es visible al resto de la aplicación a través del CCCGD. La transparencia a la heterogeneidad de la fuente de datos se logra mediante el uso del Adaptador, quien es el responsable de traducir las representaciones del modelo de objetos al modelo de la fuente de datos y viceversa. El presente proyecto se enmarca dentro del contexto global del proyecto descrito anteriormente. De esta manera, su objetivo principal es analizar las diferentes alternativas de diseño existentes para el desarrollo de la persistencia en Java, a partir de las cuales sea posible definir y desarrollar un subconjunto de la funcionalidad definida para PSeneca, correspondiente a los primeros servicios del CCDL y el Adaptador, teniendo en cuenta sus objetivos globales y otros criterios mencionados anteriormente, tales como el nivel de acoplamiento entre las capas de negocio y de datos, la facilidad de desarrollo y la portabilidad de la aplicación. Con relación a este objetivo se han definido los siguientes objetivos específicos para el proyecto: • • • • • • •. Investigar los principales factores y los problemas existentes relacionados con el diseño e implementación de la persistencia de una aplicación orientada a objetos. Analizar el problema de la impedancia objeto-relacional y las soluciones ofrecidas a este problema para un entorno Java. Explorar JDO como alternativa de persistencia para aplicaciones Java. Determinar las mejores alternativas de diseño de persistencia dentro del contexto PSeneca. Determinar la aplicabilidad de patrones de diseño dentro de las diferentes alternativas estudiadas. Diseñar e implementar la funcionalidad del proyecto PSeneca que se encuentre dentro del alcance definido para el proyecto. Realizar una implementación practica para probar las alternativas consideradas y poder comparar y concluir sobre cada una de ellas.. Teniendo en cuenta estos objetivos, el capítulo 2 de este documento presenta el estado del arte de la persistencia en Java. En el capítulo 3 se encuentra el estudio de JDO como alternativa de persistencia para aplicaciones Java. El capítulo 4 presenta el alcance y diseño de la implementación realizada del proyecto como parte de PSeneca. El capítulo 5 contiene el diseño detallado de esta implementación. En el Capítulo 6 se detalla el lenguaje de consulta implementado. En el capítulo 7 se describe el caso de estudio utilizado. El capítulo 8 muestra un análisis de resultados y comparaciones de la implementación realizada con respecto a otras alternativas existentes. Finalmente, el Capítulo 9 muestra las conclusiones del proyecto.. 6.
(7) 2. Estado del arte. Uno de los objetivos de diseño de una aplicación orientada a objetos con arquitectura multinivel consiste en descomponer una aplicación en capas con funcionalidad específica e independiente. Las capas principales de este tipo de aplicaciones son la capa de presentación, que se encarga de la interacción con el usuario; la capa de negocio, que contiene objetos que son una abstracción de entidades del mundo real y que representan conceptos claves del negocio (Core JDO, 2002); y la capa de datos, que suple los requerimientos de persistencia asociados a algunos de esos objetos de negocio. Al desarrollar un sistema de esta forma, se espera una aplicación que soporte bajo acoplamiento y alta cohesión (Larman, 1997). Sin embargo, la capa de la lógica del negocio no es completamente independiente de la capa de datos cuando esta última ha sido desarrollada empleando tecnologías relacionales. Los desarrolladores se enfrentan al problema de la impedancia, el cual hace referencia a que un modelo de objetos no tiene una equivalencia exacta con uno relacional, y por tanto es necesaria alguna transformación que ajuste su representación (Ambler, 2002). Esto conduce a la creación de una capa de persistencia que permita desacoplar ambos niveles. Dentro del contexto Java, El desarrollador cuenta con varias opciones a la hora de desarrollar su capa de persistencia, entre las cuales se encuentran especificaciones como los Enterprise JavaBeans (EJB) (EJB 2.0), los Java Data Objects (JDO) (Rusell, 2002) y ODMG (ODMG, 1997). En este capítulo se presentan estas alternativas de persistencia teniendo en cuenta que constituyen un precedente para el diseño e implementación de PSeneca, además que permiten evaluar los resultados obtenidos en comparación con dichas alternativas. JDO y ODMG son explicadas por ser dos especificaciones existentes para el manejo de la persistencia transparente de objetos, las cuales comparten muchos conceptos e ideas comunes en ese contexto. Las ideas presentes en estas especificaciones, así como el estudio de sus bondades y debilidades, constituyen un punto de partida y de referencia para PSeneca, que incorpora principios básicos y comunes al diseño de la persistencia transparente y que intenta diferenciarse en aquellos puntos que permiten ofrecer una mayor gama de soluciones, y que son los que finalmente permiten evaluar PSeneca frente a otras alternativas de persistencia existentes. Los EJB se estudian por ser la especificación a partir de la cual se diseñan gran parte de las aplicaciones transaccionales multinivel en Java. Dentro de esta especificación, es posible implementar varias alternativas de persistencia, incluyendo los Entity Beans, JDBC y JDO. Dependiendo de la alternativa elegida, la estructura y comportamiento de la aplicación puede variar considerablemente. Por tal motivo, es necesario conocer la forma en que el sistema se ve afectado por la utilización de EJBs, del mecanismo de persistencia, y de su uso conjunto. Estas consideraciones deben ser analizadas tanto por los desarrolladores de las tecnologías de persistencia como por los desarrolladores que hacen uso de esas tecnologías.. 7.
(8) 2.1. JDO. Java Data Objects es una especificación para la implementación de persistencia transparente de objetos Java. JDO utiliza una aproximación ortogonal a la persistencia de objetos, en el sentido de que esta desacoplada y es independiente de su mecanismo de implementación subyacente, y esta definida según las siguientes características, que son objetivos claves en la creación de la arquitectura JDO (Core JDO, 2002) (Rusell, 2002): •. Ortogonalidad del tipo de dato, según el cual todo dato, independiente de su tipo, debe ser persistido de una misma manera. JDO permite el manejo de persistencia para toda la jerarquía de clases definida por Java y por el usuario, excepto aquellas cuyo estado dependan del ambiente de operación (como File, InputStream, Socket, etc.).. •. Independencia de la persistencia, que indica que el código de la aplicación debe ser indiferente de si esta manejando datos persistentes. En JDO el código que implementa la lógica del negocio esta separado y es independiente del código que conoce la implementación de la persistencia.. •. Persistencia por alcanzabilidad, según la cual el ciclo de vida de un objeto y su estado persistente incluye a aquellos objetos persistentes que son referenciados por el.. •. La persistencia esta definida a nivel de objeto. Para una misma clase pueden haber objetos transientes y persistentes.. •. La persistencia esta basada en invocación de métodos, un objeto es persistido utilizando el método makePersistent() de la clase PersistenceManager de JDO.. 2.1.1 Arquitectura Una aplicación JDO consta de los siguientes componentes (Monday): • • • • •. La aplicación, que hace uso de los APIs de JDO Objetos del negocio incluyendo objetos transientes y objetos persistentes, estos últimos implementan la interfaz PersistenceCapable y son manejados por una instancia de PersistenceManager El PersistenceManager es el punto de acceso a JDO y es el encargado de las transacciones y las consultas de objetos Una fuente de datos Un archivo de metadatos, en formato XML y que describe las asociaciones y propiedades de los atributos de las clases persistentes de la aplicación. 8.
(9) Figura 2. Arquitectura de una aplicación JDO. Fuente: Monday. PersistenceManager es una interfaz que define los métodos principales encargados del. control y administración de objetos persistentes JDO, los cuales pueden ser de este tipo al implementar la interfaz PersistentCapable, que indica el hecho de que un objeto tiene un estado que debe ser persistido por la implementación JDO que se utilice. Instancias de PersistenceManager pueden ser obtenidas a partir de una clase PersistenceManagerFactory, la cual funciona como un factory y un pool de objetos de ese tipo. Como se mencionó anteriormente, la persistencia de un objeto en JDO debe ser indicada utilizando métodos definidos en PersistenceManager, tales como makePersistent() o deletePersistent(), además de estar definidos, regularmente, dentro del entorno de una transacción, para lo cual se pueden utilizar los métodos commit(), begin() y rollback() del objeto Transaction, obtenido a partir de un PersistenceManager mediante su método currentTransaction(). En la especificación JDO se clasifican las aplicaciones Java dentro de dos ambientes, nombrados como no manejados y manejados. El primer caso corresponde a aplicaciones Java, de 2 niveles, que solicitan los recursos directamente, en las cuales el desarrollador explícitamente hace los llamados necesarios a las clases que manejan aspectos como las persistencia, incluyendo los métodos nombrados anteriormente. Un ejemplo del código de este tipo de ambiente es el que se muestra a continuación, en el cual se persiste una instancia de un objeto PersistenceCapable: //se obtiene un PersistenceManager a partir de un //PersistenceManagerFactory, pmf en este caso PersistenceManager mgr = pmf.getPersistenceManager(); //inicio de la transacción mgr.currentTransaction().begin(); //se crea un nuevo objeto cliente, definido como PersistenceCapable Cliente cliente = new Cliente(“a”); //se persiste el objeto cliente. 9.
(10) mgr.makePersistent(cliente); //confirmación transacción mgr.curentTransaction().commit(); Código 1. persistencia de un objeto con un PersitenceManager. El segundo caso, de ambientes manejados, corresponde a aplicaciones multi-nivel J2EE, en las cuales se utiliza un servidor de aplicaciones para acceder a los recursos middleware necesitados. En este caso el servidor puede ser el encargado de invocar los métodos necesarios para obtener los recursos transaccionales requeridos por JDO, indicando el desarrollador esta necesidad declarativamente y no en el código. Más adelante se amplía el uso de JDO en un ambiente manejado J2EE.. 2.1.2 JDOQL JDOQL es el lenguaje de consulta utilizado por JDO, el cual se utiliza como vía de acceso a los objetos de una aplicación. Este lenguaje provee una sintaxis tipo Java, permitiendo a los desarrolladores utilizar un mismo modelo de programación para desarrollar la lógica del negocio e implementar los mecanismos de acceso a fuentes de datos (Jordan, JDOQL). Al mismo tiempo que ofrece una interfaz uniforme de programación, JDOQL independiza y oculta completamente los detalles y lenguajes específicos utilizados para la generación de la persistencia de la aplicación. Lo anterior garantiza el cumplimiento del objetivo de persistencia transparente propuesto por JDO, así como facilita la portabilidad del programa entre diferentes mecanismos de persistencia e implementaciones de la especificación. Además, al ser un lenguaje de alto nivel, permite su optimización de acuerdo a la implementación específica que se utilice. JDO provee la interfaz Query para la ejecución de consultas, la cual es obtenida a partir de una instancia de PersistenceManager, utilizando uno de los métodos newQuery(…) definidos en esta interfaz. Los componentes de un query incluyen las partes correspondientes a una consulta asociativa, tales como la Extensión o Conjunto de instancias candidatas de una clase sobre las cuales se ejecuta la consulta, el filtro que deben cumplir estas instancias para formar parte del resultado, y el orden en que se retornan los objetos de la respuesta. Adicionalmente se pueden declarar parámetros de tipos de objetos Java que pueden ser pasados a la consulta en el momento de su ejecución, y variables que permiten definir o asignar nombres a objetos utilizados dentro de una consulta y que se pueden utilizar para navegar a través de las asociaciones definidas para los objetos (EJB 2.0) (Ross,2003). El resultado de una consulta JDOQL es una instancia de Object, que para el caso de la especificación JDO 1.0 corresponde únicamente a un Collection con los objetos obtenidos. Esta especificación no incluye la proyección o selección de atributos específicos de una clase, sin embargo se retorna Object y no Collection para permitir la extensibilidad del lenguaje y retornar objetos diferentes a este. JDOQL tampoco provee otras características que se pueden encontrar en lenguajes de consulta como SQL o OQL, tales como el uso de funciones y métodos de agregación de datos, o la posibilidad de. 10.
(11) actualizar o eliminar conjuntos de datos a partir de una consulta, limitando la aplicabilidad del lenguaje en sistemas empresariales que necesitan gran control y flexibilidad en el manejo de su información. Sin embargo, las características actuales de JDOQL están alineadas con los objetivos de transparencia que son fundamentales en el diseño de JDO. Ampliaciones al lenguaje se han planeado para futuras especificaciones de JDO (Rusell 2002).. 2.2. EJB. Enterprise JavaBeans es una arquitectura de componentes del lado del servidor que simplifica el proceso de construcción de componentes empresariales distribuidos en Java (Rodman, Ambler & Jewell 2002). EJB permite escribir rápidamente componentes escalables, confiables y seguros sin necesidad de construir la arquitectura de servicios distribuidos, permitiendo al desarrollador centrarse en la lógica del negocio y producir una aplicación portable y reusable en poco tiempo. La especificación 2.0 de EJB (EJB 2.0) define tres tipos de componentes, los cuales poseen como características comunes el hecho de ser distribuidos, transaccionales y con un ciclo de vida controlado por el contenedor en el que son desplegados. Estos componentes son: Session Beans: modelan procesos del negocio, su intención es encapsular el procesamiento que debe ocurrir en respuesta a una solicitud, representando una sesión interactiva entre un cliente y el servidor (Ross, 2003). Dependiendo de si se debe mantener el estado de esa conversación entre distintas invocaciones del cliente o no, estos Session Beans se dividen en Stateful y Staless respectivamente. Message-driven Beans: similares a los sessions beans en cuanto a que representan un procesamiento, pero invocados asincrónicamente a través de mensajes. Entity Beans: modelan datos del negocio, son objetos Java que representan información de una fuente de datos. Los Entity Beans fueron diseñados con los siguientes objetivos (Marinescu, 2000): 1. Proveer una manera estándar de persistir el modelo del dominio. Antes de los entity beans, la gente tenía que escribir su propio framework de persistencia que dependiera de traductores relacionales propietarios. 2. Encapsular el mecanismo de persistencia. El uso de BMP o CMP esta oculto detrás de los entity beans. 3. Ser objetos distribuidos, accesibles desde cualquier lugar. 4. Ser objetos transaccionales. Los entity beans utilizan persistencia basada en funciones (Hapner, Rusell, FAQ: EJB 2.0 CMP and JDO) (Suresh, JDO vs. EJB), implementándola a partir de una serie de métodos definidos, en contraste a la persistencia transparente.. 11.
(12) 2.3. Uso de JDO en J2EE. Uno de los objetivos de diseño de JDO es permitir su uso en ambientes manejados, específicamente J2EE. Para permitir esto, una implementación JDO debe emplear la arquitectura de conexión de J2EE (JCA), la cual define una serie de contratos que permiten conectar e interactuar de manera estándar sistemas de información empresariales de diversos tipos con J2EE (Core JDO, 2002). Existen varios escenarios en los cuales JDO puede proveer servicios de persistencia en J2EE, incluyendo su uso dentro de la capa web en servlets o JSP, en cuyo caso se implementa como un ambiente no manejado, o dentro de los componentes EJB (Ross, 2003). Este último caso corresponde a los ambientes manejados y cuenta a su vez con distintos escenarios o configuraciones (Ross, 2003): : • Integración de JDO con stateless Session Beans • Integración de JDO con stateful Session Beans • Integración de JDO con Entity Beans • Integración de JDO con Message-driven Beans Independiente. del. caso,. algunas características de uso se mantienen. Un PeristenceManagerFactory es buscado a través de JNDI al principio del ciclo de vida del componente y mantenido como un atributo de la clase. Este atributo es buscado durante el llamado a los métodos setSessionContext(), setEntityContext() y setMessageDrivenContext() de cada Bean. Para transacciones manejadas por el contenedor (CMT), un PersistenceManager debe ser obtenido y cerrado durante cada invocación de un método, para liberar sus recursos y permitir que sea retornado al pool. Al usar CMT el contenedor es responsable de demarcar las transacciones usando un objeto UserTransaction de J2EE, por lo que no es necesario utilizar el objeto Transaction de JDO. Si se utiliza Staful Sessions Beans con Transacciones manejadas por el Bean (BMT), el desarrollador puede hacer uso de UserTransaction o de Transaction para demarcar sus transacciones, además de que puede mantener recursos de PersistenceManager por más tiempo, por lo que no hay que cerrarlo en cada invocación de un método.. 2.3.1 Session Beans y JDO Aunque los Entity Beans fueron diseñados para encapsular la lógica de acceso a datos, es común usar los Session Beans para realizar este procesamiento sin utilizar los Entity Beans. En estos casos JDO provee una forma transparente de realizar esta lógica de persistencia, usando los servicios ofrecidos por JDO para las operaciones de Creación, Recuperación, Actualización y Eliminación de datos (CRUD), junto con otros servicios relacionados con la persistencia como el manejo de cache, sincronización, pool de conexiones y transacciones. En vez de usar Entity Beans, se utilizan objetos normales de java de contienen la lógica del negocio y son persistidos por JDO. Lo que los Sessions Beans ofrecen en esta configuración es la posibilidad de distribuir y comunicar remotamente estos. 12.
(13) objetos, ofrecer servicios de transacciones distribuidas y de seguridad (Hapner, Rusell, FAQ: EJB 2.0 CMP and JDO) empleando las prestaciones ofrecidas por el contenedor, sin incurrir en los costos asociados a un componente como los Entity Beans.. 2.3.2 Entity Beans y JDO En este escenario se utiliza JDO como el mecanismo de persistencia de los Entity Beans. En el caso de persistencia manejado por el contenedor (CMP) un servidor de aplicaciones podría hacer uso de JDO para implementar sus servicios de persistencia automática. Si se utiliza persistencia manejada por el Bean (BMP), el desarrollador del componente podría usar JDO como una alternativa de persistencia a JDBC. Otra posibilidad de uso de JDO y Entity Beans es una similar a la ofrecida por los Session Beans, de envolver las clases de JDO (utilizando una estrategia BMP) con estos componentes para permitir que sean accesibles directamente, en vez de usar una fachada de sesión, lo cual implica un mayor grado de autonomía y funcionalidad de las clases JDO (Hapner, Rusell, FAQ: EJB 2.0 CMP and JDO).. 2.4. JDO vs. Entity Beans. En las secciones anteriores se introdujeron algunos conceptos básicos de JDO y EJB, y la forma en que estas dos especificaciones podrían ser usadas juntas. Al momento de decidir cuando es mejor una opción u otra, es necesario entender los requerimientos de la aplicación y la manera en que estas tecnologías pueden resolver sus necesidades de persistencia. De acuerdo a Hapner y Rusell: CMP provee un mecanismo estándar para implementar componentes persistentes del negocio. CMP no es una facilidad general de persistencia para la plataforma Java. CMP provee acceso seguro, distribuido y transaccional a datos persistentes, con una interfaz portable garantizada. CMP esta basado en un modelo funcional de acceso a datos. No soporta persistencia transparente de variables de instancias de Java (…) JDO es una arquitectura que provee una manera estándar para persistir transparentemente objetos planos Java. Esta diseñado para trabajar en múltiples capas de una arquitectura empresarial, incluyendo J2SE, capa Web, y Servidores de Aplicación. El por si mismo no provee objetos distribuidos, transacciones distribuidas, o servicios de seguridad, aunque puede ser integrado con un contenedor EJB que provea esos servicios. CMP es para persistir componentes distribuidos construidos específicamente para el API de los componentes entity bean. JDO esta desarrollado a través de locales, ricos modelos de objetos no ligados a un API particular. Desarrolladores pueden escoger entre estas tecnologías evaluando sus requerimientos (componentes persistentes u objetos persistentes). (Hapner, Rusell, FAQ: EJB 2.0 CMP and JDO). Del párrafo anterior se concluye que las metas de diseño de CMP y JDO difieren en varios aspectos, teniendo en común el proveer una manera estándar para implementar la. 13.
(14) persistencia de un modelo de negocios, diferenciándose en la aproximación que siguen para su implementación, funcional en el caso de CMP y ortogonal del lenguaje para JDO. En cuanto a las decisiones de diseño de los Entity Beans que se refieren a ser distribuidos y transaccionales, algunos analistas (Marinescu, 2000) consideran tales decisiones como equivocadas, dado que es un patrón común de diseño envolver un Entity Bean mediante un Session Bean (Marinescu,2002), siendo este último quien provee la interfaz remota del componente y los servicios transaccionales, siendo por tanto un gasto innecesario que el Entity Bean provea estos servicios. Aunque los Entity Beans pueden usar interfaces locales, esto cambia la semántica de la aplicación. En cualquier caso, ellos añaden un sobrecosto transaccional y requieren configuración en los descriptores, son componentes pesados debido a todo el manejo del ciclo de vida que requieren y que el contenedor controla, y puesto a que mucha gente los utiliza a través de Session Beans, se requiere mucho código extra que puede no tener sentido (Marinescu, 2000). Contra este fundamento se podría indicar la existencia de situaciones donde es mejor exponer directamente la capa de datos como un servicio remoto, pero no se encuentran muchos casos donde esto sea justificable. Independientemente de si los Entity Beans son accedidos remotamente o a través de Session Beans, ellos por si mismos poseen o carecen de ciertas características que los hacen inadecuados en un entorno donde los principales requerimientos son los de poseer una robusta capa de persistencia para un modelo del negocio, modelo que regularmente contiene una estructura compleja y que debe ser lo mas transparente posible de la infraestructura de datos que los soporta, con el fin de cumplir con las muy comunes solicitudes de actualización, ampliación y cambios de las reglas del negocio que afectan el modelo del mundo y por tanto su esquema de persistencia(Suresh,JDO vs EJB). A continuación se provee una lista de los principales aspectos que afectan el uso de los Entity Beans y su relación con JDO, tomada a partir de (Ross, 2002): Acceso Remoto: Como se mencionó anteriormente, los Entity Beans son componentes remotos aun cuando se aconseja usarlos localmente, lo que es posible desde la especificación 2.0 por medio de las interfaces locales y que mitiga los costos asociados con las invocaciones remotas. Los objetos JDO no son remotos, ellos satisfacen los requerimientos de persistencia en la JVM que emplea JDO. Cache: Los Entity Beans tienen cache manejado por el servidor de aplicaciones. JDO tiene cache manejado por el Persistence Manager. Implementaciones avanzadas de ambas tecnologías soportan caches distribuidos con mensajes inter-cache para mantener la consistencia de los datos. Complejidad del componente: Los Entity Beans son componentes complejos que requieren de dos interfaces, una clase y posiblemente una clase de la llave primaria. Adicionalmente deben ser buscados a través de JNDI. Las instancias de JDO son objetos que se quiere que persistan. No se necesita implementar ninguna interfaz en el código fuente, tan solo contar con un constructor vació que puede ser privado si se desea. 14.
(15) Complejidad de implementación: Los Entity Beans están sujetos a una serie de contratos, relativos a la implementación de los métodos de su ciclo de vida. Con JDO se puede tomar un objeto escrito anteriormente y almacenarlo a través de JDO sin ninguna modificación (Excepto el constructor vacío). Complejidad de búsqueda: Cada interfaz home del Entity Bean es buscado a través de JNDI independientemente. Con JNDI se puede ubicar el PersistenceManagerFactory y utilizar un PersistenceManager a partir de el para obtener todas las instancias de objetos JDO. Polimorfismo: Los Entity Beans no son polimórficos, no soportan herencia directamente, aunque se pueden heredar las interfaces del componente. Los métodos de búsqueda retornan instancias del entity incluso aunque correspondan a una subclase de ellos. JDO es polimórfico, es posible realizar consultas y obtener clases y subclases de un Extent. Persistencia transparente: JDO soporta persistencia por alcanzabilidad, mientras los Entity Beans no. Es posible navegar por referencias de objetos en JDO. Algo similar se puede hacer con los Entity Beans por medio de relaciones manejadas por el contenedor (CMR). Transaccionalidad: Entity Beans y JDO soportan transacciones que pueden ser manejadas por el contenedor de aplicaciones. JDO adicionalmente soporta operaciones no transaccionales. JDO también soporta demarcación de transacciones fuera del contexto de J2EE, lo cual puede ser útil para aplicaciones que necesitan acceso transaccional a los datos sin pasar por los EJB. Seguridad: Los Entity Beans permiten autorización a nivel método, la cual es implementada declarativamente usando los descriptores de despliegue. JDO no ofrece este servicio. Session Fachada: Tanto los Entity Beans como instancias de JDO pueden ser envueltos por un Session Bean de Fachada, el cual provee servicios transaccionales y de seguridad. Reuso: Los Entity Beans solo pueden ser usados dentro de un contenedor EJB, mientras instancias JDO pueden ser usadas desde múltiples capas. Modelo de objetos: En EJB regularmente se crea una división de manejo de estado en los Entity beans y los value objects y de comportamiento en los Session Beans, lo cual debería ir junto según el paradigma de objetos. JDO maneja objetos, que como tales tienen estado y comportamiento, haciéndolos inherentemente mas reutilizables. Algunos expertos consideran que los JDO lucen como lo que los Entity Beans debieron ser. La especificación 2.0 de EJB no incluye a JDO, JDO se encuentra apenas en su especificación inicial, y es necesario más implementaciones de esta especificación y más desarrollo de esta tecnología dentro de J2EE para determinar exactamente la forma en que JDO puede ser usada. Sin embargo JDO parece contener los elementos necesarios para 15.
(16) suplir con los requerimientos de persistencia de una aplicación empresarial promedio, siendo viable en un amplio rango de entornos y contextos.. 2.5. ODMG. El grupo ODMG (Object Database Management Group) (ODMG, 1997) define un estándar para bases de datos orientadas a objetos, incluyendo como elementos de su especificación un modelo de objetos común, un lenguaje de especificación de objetos y un lenguaje de consulta de objetos (OQL), junto con los enlaces necesarios del modelo a C++, Smalltalk y Java. Su objetivo principal es crear un estándar para la industria de bases de datos orientadas a objetos (ODBMS) y permitir la portabilidad entre aplicaciones de ODBMS que sigan el estándar. Lo anterior incluye la portabilidad del esquema de datos, del enlace del lenguaje de programación, y de los lenguajes de manipulación y consulta de objetos. El estándar ODMG ha sido creado de tal manera que se adapte a las características propias de los sistemas ODBMS, que ofrecen una manera transparente y homogénea de integración con lenguajes de programación orientados a objetos, evitando tener que utilizar dos esquemas de programación distintos, eliminado la necesidad de traducción entre los dos niveles, y obteniendo mejoras de desempeño al usar un cache dentro de las aplicaciones (ODMG, 1997). Estos sistemas ODBMS proveen una visión transparente de los objetos a los lenguajes de programación que los usan y añaden las características propias de un sistema manejador de bases de datos como persistencia, consultas asociativas y control de concurrencia, entre otros. De lo anterior se pueden obtener similitudes y diferencias entre ODMG y JDO. Las dos especificaciones se ocupan de la persistencia transparente de objetos y de la portabilidad de este tipo de aplicaciones entre diferentes implementaciones de persistencia. La diferencia se encuentra en el alcance de la portabilidad entre los lenguajes y los sistemas manejadores de persistencia; mientras ODMG ha sido diseñado para permitir intercambiar una aplicación entre diferentes lenguajes y diferentes sistemas manejadores de bases de datos orientados a objetos, JDO se ha diseñado para permitir portar transparentemente una aplicación desarrollada en Java entre diferentes esquemas de persistencia, incluyendo bases de datos orientadas a objetos, relacionales y otros. Ambos soportan el manejo de instancias de objetos persistentes en el cache de la aplicación, asegurando la existencia de una sola copia por objeto (Jordan, Comparing JDO and ODMG). Ambos sistemas implementan persistencia por alcanzabilidad y permiten la navegación a través de referencias de objetos, obteniéndolos del cache según se necesiten, todas estas características propias de un sistema de manejo de persistencia transparente (Jordan, Comparing JDO and ODMG). Entre otras diferencias entre ODMG y JDO se encuentran (Jordan, Comparing JDO and ODMG) (Detailed Comparison of ODMG 3.0 and JDO): • •. JDO provee tres formas de identidad: de la fuente de datos, de aplicación y no durable, mientras ODMG provee solo identidad de la fuente de datos. ODMG utiliza su propio conjunto de interfaces de colecciones, que extienden de las interfaces definidas en java, mientras JDO utiliza directamente estas últimas.. 16.
(17) • • • •. ODMG permite control de concurrencia pesimista y optimista, mientras JDO exige el primero y tiene el segundo como opcional. Además JDO tiene más opciones que permiten ajustar el manejo del control de concurrencia. Métodos de Callback definidos para JDO pero no para ODMG Soporte para transacciones distribuidas y ambientes manejados como J2EE en el caso de JDO ODMG utiliza bloqueo explicito de objetos mientras en JDO es implícito. Una mayor diferencia entre ambos modelos es en sus correspondientes lenguajes de consulta. Las siguientes son características propias definidas en OQL (ODMG, 1997):. 2.5.1 Principios de OQL OQL es cercano a SQL 92, añadiendo los conceptos de objetos como polimorfismo, identidad de objetos, navegabilidad y objetos complejos. Provee primitivas de alto nivel para tratar con objetos y otras para trabajar eficientemente con estructuras, listas y arreglos. Es un lenguaje funcional y no es computacionalmente completo. No provee operadores explícitos de actualización sino que invoca operaciones en objetos definidos para ese propósito. Es declarativo, y así puede ser optimizado. Entrada y resultados de las consultas: Una consulta en OQL puede referirse a nombres que son cualquier clase de objetos, incluyendo estructuras, colecciones y literales. Identidad: Se soporta identidad de objetos a través de sus OID’s y de literales. Navegación: Es posible navegar desde un objeto a partir de sus atributos o asociaciones. Esto incluye el uso de predicados para los objetos y de joins. Valores nulos: Se pueden diferenciar objetos nulos o no definidos. Invocación de métodos: Se permite la ejecución de métodos dentro de OQL siempre y cuando el resultado del método concuerde con el tipo esperado de la consulta. Polimorfismo: Es posible tener operaciones que involucren una jerarquía de clases y subclases. Tiene relación con el enlace tardío. Dependiendo del tipo de objeto que represente una consulta puede ser su resultado esperado. Se puede declarar explícitamente la clase esperada de una consulta. Operador de composición: Es posible usar operaciones del álgebra tales como unión, intersección, etc. y funciones agregadas como max, min, etc. En resumen, OQL ofrece un lenguaje más rico y extenso que JDOQL, aprovechando las ventajas propias de los objetos como polimorfismo, navegación a través de las asociaciones e invocación de métodos, y empleando las facilidades propias de un lenguaje de consulta similar a SQL como proyección, uso de funciones y de diferentes tipos de objetos como. 17.
(18) estructuras, colecciones y literales. ODMG provee filtros y consultas más complejas que las posibles en JDO. Por otro lado, JDO presenta características únicas que ODMG no implementa (Jordan, Comparing JDO and ODMG), como retener objetos entre transacciones, instancias y campos transaccionales transientes, llamados Callback desde JDO a las instancias para informarle sobre ciertos eventos en el cache, manejo de nulls, invocación de métodos sobre el cache, objetos anidados, integración con ambientes manejados como J2EE y compatibilidad binaria entre diferentes implementaciones, todas las cuales deben seguir un contrato para el proceso de enhancer de las clases. Además JDO cuenta con más implementaciones que las existentes en ODMG, a pesar de su corto tiempo de existencia, lo que puede ser una demostración del auge y aceptación que JDO esta teniendo dentro de la industria.. 2.6. Resumen y conclusiones del estado del arte. Tanto JDO como J2EE son especificaciones relativamente nuevas que se encuentran en un proceso de evolución y adopción dentro de la industria. Si bien los Entity Beans y JDO son dos opciones claras para el manejo de persistencia dentro de J2EE, ambas presentan limitaciones que les impiden ofrecer una solución completa en este campo. Los Entity Beans garantizan un manejo sincrónico y transaccional de los objetos con respecto a las fuentes de datos, estandarizan y encapsulan las capas de persistencia, al tiempo que poseen características que limitan la capacidad de su desarrollo y aumentan la complejidad de este proceso, siendo además insuficientes para algunos casos mecanismos como la persistencia manejada por el contenedor (CMP) y su lenguaje de consulta EJBQL. JDO por su parte ha sido diseñado para trabajar integradamente con J2EE, presentando muchas características de la persistencia transparente que facilitan el proceso de desarrollo de la aplicación y sus objetos del negocio. Sin embargo ofrece un lenguaje limitado de consulta, puede limitar la flexibilidad del desarrollo en las capas de datos, y puede no ser totalmente transparente, tal como se detalla en el capítulo 3. PSeneca es una alternativa para la persistencia transparente de objetos. Por esta razón posee características fundamentales presentes también en ODMG y JDO, entre ellas que la forma de persistir y recuperar objetos debe hacerse de manera transparente y debe ser independiente de la fuente de datos. PSeneca agrega a esta definición la transparencia a la distribución de los datos, que es una característica que también puede ser ofrecida por los componentes EJB. Al igual que ocurre con JDO, PSeneca tiene como objetivo integrarse dentro de un contenedor de componentes de negocio, aunque en el caso de PSeneca no se limita tal contenedor a uno que sea compatible con la especificación EJB. El lenguaje de consulta propuesto en PSeneca es más cercano al lenguaje OQL de ODMG que al lenguaje JDOQL de JDO, debido al mayor número de posibilidades que ofrece OQL frente a JDOQL.. 18.
(19) 3. Análisis de JDO como mecanismo de persistencia. En este capítulo se presenta, a través de un ejemplo, el análisis de fortalezas y debilidades de JDO desde el punto de vista de diseño. Inicialmente se presentan las principales características de JDO y la forma en que estas características determinan parte de la estructura y comportamiento de una aplicación. Posteriormente se muestran los cambios introducidos por el uso de JDO al modelo de clases que naturalmente resulta del análisis del negocio. Finalmente se presenta la forma en que el uso de JDO y J2EE determina el diseño de algunos aspectos de la aplicación como el lenguaje de consulta o las transacciones. El estudio de JDO, teniendo en cuenta que se trata de una especificación importante para el manejo de la persistencia transparente en Java, permite dar las bases para un acertado análisis y evaluación de PSeneca, al tiempo que permite brindar un mayor conocimiento de los aspectos de diseño existentes en este tipo de alternativas de persistencia.. 3.1. Características principales de la especificación JDO. Las aplicaciones que utilizan JDO deben poseer algunas características comunes para ajustarse a esta especificación. Estas características incluyen la declaración de clases y atributos persistentes y la forma de identificar, recuperar y persistir objetos.. 3.1.1 Declaración de la persistencia En JDO se mantiene un modelo de objetos puro que mantiene las propiedades y relaciones definidas inicialmente por el diseñador del sistema. Además, estas clases dejan de ser las responsables directas de su persistencia y recuperación, siendo la implementación de JDO quien se encarga de esto, según se especifique declarativamente en un archivo XML, en el cual se definen las clases y atributos persistentes, y posiblemente el esquema de traducción a la base de datos. La especificación de JDO (Rusell, 2002) define cuales tipos de datos deben poder persistirse, y cuales no se pueden persistir. Además de los tipos básicos, se debe indicar en el descriptor los atributos de tipo Collection y el tipo de objetos que van a contener, esto con el fin de que la implementación pueda conocer como asociar correctamente instancias de estos objetos de manera persistente.. 3.1.2 Definición de identidad de los objetos persistentes JDO define tres tipos de identidad posibles para los objetos persistentes, tales como identidad de la aplicación, de la fuente de datos y no durable. En la identidad de la aplicación el desarrollador es responsable de definir el campo o los campos que identifican a un objeto, y tiene sentido para aquellos objetos que tienen una identidad natural. En la identidad de la fuente de datos es la implementación de JDO quien asigna los identificadores, y se puede aplicar para obtener identificadores que no tengan significado del negocio. La identidad no durable no crea un identificador para el objeto en la fuente de. 19.
(20) datos, y puede utilizarse cuando no es necesario distinguir entre instancias de objetos de una clase. Cada tipo de identidad tiene sus ventajas y desventajas. Lo primero que se debe tener en cuenta es si la implementación de JDO elegida soporta el tipo de identidad escogido, ya que es opcional cual soportar, de aplicación o de la fuente de datos, aunque regularmente se soportan todas. La identidad manejada por la aplicación ofrece más flexibilidad al desarrollador, aunque requiere que éste escriba más código al requerir la creación de clases que funcionen como identificadores (Richardson, 2003). Además, esta forma facilita la búsqueda de objetos por sus identificadores, los cuales pueden ser fácilmente recordados por los usuarios del sistema. Por otro lado, la identidad manejada por la fuente de datos maneja automáticamente los identificadores de forma que sea posible reconstruir todo el grafo de objetos de una aplicación sin necesidad de que el desarrollador asigne más atributos a sus clases, pero dificulta la búsqueda basada en dichos identificadores.. 3.1.3 Recuperación y almacenamiento de objetos El diseño de JDO define la forma en que se debe manejar el almacenamiento y recuperación de objetos, teniendo en cuenta las posibilidades de obtener raíces de acceso y navegación de objetos usando JDOQL y la persistencia por alcanzabilidad propia del modelo. Las raíces de persistencia son aquellos objetos a partir de los cuales se puede tener acceso al resto de la aplicación utilizando sus referencias a otros objetos. Utilizando JDOQL (Jordan, JDOQL) se puede tener acceso a estas raíces de persistencia o incluso emplear dicho lenguaje para navegar por las referencias hasta obtener los objetos deseados. Lo anterior hace referencia al concepto de persistencia por alcanzabilidad, utilizado por JDO, según el cual una clase es hecha persistente si es alcanzada o referenciada por otra clase persistente, y aplica tanto para almacenamiento como para recuperación o navegación de objetos. En JDO existe la restricción a esta definición de que las clases alcanzadas también deben haber sido definidas como persistentes para poder ser persistidas. El desarrollador de la aplicación debe conocer y tener presente estos conceptos de la persistencia transparente para ser capaz de decidir sus raíces de persistencia y manejar adecuadamente la forma en que recupera y persiste sus objetos, de forma tal que utilice la persistencia por alcanzabilidad adecuadamente y aproveche la transparencia que esta provee. Además debe tener un conocimiento del API de JDO con el fin de que pueda implementar estos conceptos de forma apropiada.. 3.2. Caso de estudio. En esta sección se presenta la descripción de la aplicación desarrollada con JDO, incluyendo las decisiones de diseño tomadas durante su desarrollo. Estas decisiones resultan de las características propias de JDO y de su uso dentro de la plataforma J2EE.. 20.
(21) 3.2.1 Requerimientos Funcionales La aplicación del club de squash permite la administración de canchas y clientes registrados en el sistema, así como el registro de las reservas realizadas por estos clientes. Esta aplicación realiza el control de canchas reservadas y disponibles para un periodo de tiempo dado y permite generar la facturación a los clientes con base en las reservas que hayan efectuado. La lista completa de requerimientos funcionales se encuentra en el capítulo 7.. 3.2.2 Diseño de la capa del negocio Para la aplicación del club de squash se creó la estructura de clases que se muestra en la Figura 3. La clase SquashRepositorio es la encargada de la interacción con JDO. SquashSessionBean es un Session Bean que representa el controlador de la aplicación, el cual expone los servicios ofrecidos por la aplicación y presta los servicios remotos y de transaccionalidad propios de los EJB. Las clases Cancha, Reserva y Cliente representan conceptos de negocio que son persistentes, son clases planas Java que contienen la lógica del negocio. Cancha. * SquashSessionBean. 1. *. Reserva. * Cliente. * *. *. 1. *. Parametros 1 negocio. SquashRepositorio 1. JDO J2EE. Figura 3. Diagrama de clases para la aplicación del club de squash. 3.2.2.1 Declaración de la persistencia para el caso de estudio Las clases que representan conceptos persistentes para la aplicación del club de squash son Cancha, Reserva, Cliente y Parámetros. Estas clases se declaran como persistentes en un archivo XML (ver sección 7.4.1) cuyo nombre corresponde al nombre del paquete de las clases. Nótese que el manejo de la implementación de la persistencia no se programa dentro del código de la aplicación, sino que se declara en un archivo separado. En este archivo se define además el tipo de identidad que utiliza cada clase y el tipo de objetos que mantienen las colecciones de las clases Cliente y Cancha, los cuales son de tipo Reserva en ambos casos. Al definir los atributos persistentes de la aplicación se. 21.
(22) debe tener en cuenta que la implementación de JDO soporte los tipos de datos utilizados en el código.. 3.2.2.2 Manejo de identidad para el caso de estudio Las clases Cliente y Cancha poseen los atributos cédula y número que respectivamente pueden servir para formar identificadores manejados por la aplicación, facilitando además las búsquedas por esos criterios. Para el caso de la reserva se tiene un consecutivo que es asignado por el sistema. De usarse identidad manejada por la fuente de datos, este consecutivo no sería visible para el cliente de la aplicación, quien lo utiliza como uno de sus criterios de búsqueda. Por esta razón se emplea también identidad manejada por la aplicación para las reservas, siendo esta la encargada de generar y asignar los consecutivos mencionados.. 3.2.2.3 Recuperación y almacenamiento de objetos utilizando JDO Como se muestra en la Figura 3, la clase controladora de la aplicación utiliza la clase SquashRepositorio para solicitar los servicios de persistencia, y esta a su vez es la encargada de hacer la invocación de los métodos específicos de JDO. Por lo tanto esta clase tiene conocimiento de las clases del negocio, tal como lo muestran las relaciones de dependencia. Esta clase utiliza los servicios de javax.jdo.PersistenceManager para persistir y recuperar los objetos de las clases definidas como Persistentes.. 3.3. Análisis de la utilización de JDO. 3.3.1 Impacto del uso de JDO y J2EE sobre la estructura de la aplicación Al diseñar una aplicación que emplee JDO y J2EE, y con el fin de lograr obtener las características de bajo acoplamiento y alta cohesión, se tendrán los siguientes tipos de clases en la capa del negocio: • • •. Clases planas Java que representan conceptos del negocio y que no tienen conocimiento de que son persistentes Componentes Session Bean de fachada que prestan los servicios de transaccionalidad y acceso remoto a la aplicación Clases encargadas de la interacción con el API de JDO para obtener los servicios de persistencia y recuperación de objetos.. Esta separación de responsabilidades en clases especializadas disminuye el acoplamiento entre las diferentes tecnologías elegidas, aumenta la mantenibilidad de los objetos del negocio y facilita el proceso de pruebas del software (Richardson, 2003). Además de la creación de estas clases, se define en un archivo XML cuales de ellas son persistentes, junto con los atributos que persistirán y la forma de identificarlas. De esta manera se separa el. 22.
(23) código que contiene la lógica del negocio del mecanismo de persistencia utilizado por el sistema. El diseñador de la aplicación debe conocer que tipos de datos pueden ser persistentes de acuerdo con la especificación de JDO y debe conocer la forma en que JDO recupera y almacena los objetos. El modo en que se realice esta persistencia puede afectar la estructura de clases y atributos del modelo del negocio, con el fin de estar acorde con los requerimientos de la especificación, es decir, con el fin de que estas clases y atributos sean del tipo soportado por JDO como persistentes. Además, el diseñador debe tomar otras decisiones relativas a la estructura de clases de la aplicación, como el tipo de identidad de cada una de sus clases persistentes teniendo en cuenta las ventajas y desventajas de cada una de ellas, la estructura de clases que interactúan con el API de JDO, o cuando sus clases deben considerarse como clases de primer tipo o de segundo tipo. Este último punto se refiere a si una clase es persistente por si misma o si se encuentra asociada a otra clase persistente que se encarga de su persistencia. Dependiendo del tipo que se elija, una implementación de JDO puede variar la forma en que recupera o almacena un objeto con el tipo definido, impactando finalmente el desempeño de la aplicación.. 3.3.2 Value Objects Un patrón comúnmente usado en J2EE es el Value Object o Data Transfer Object (DTO) (Marinescu, 2002). Este patrón permite transferir un grupo relacionado de información entre diferentes capas de la aplicación en un número reducido de invocaciones remotas, disminuyendo el tráfico en la red. Esta razón para usar los Value Objects o DTO’s aplica también para aplicaciones J2EE que utilizan JDO como su mecanismo de persistencia. Existen dos alternativas para implementar este patrón. La primera de ellas consiste en crear nuevas clases que sean los valueobjects que la aplicación utiliza como parámetros y valores de retornos en varios de sus métodos, tal como se haría en una aplicación J2EE con EJB’s y sin JDO. Una segunda alternativa consiste en utilizar las mismas clases de negocio como valueobjects (Rose, 2003) (Core JDO, 2002), posiblemente implementando una interfaz que defina los métodos get de los atributos que se quieren mostrar de la clase, tal como se muestra en la Figura 4 para las clases Cliente y Reserva. La interfaz java.io.Serializable hace posible que las clases que la implementan puedan ser enviadas a través de un flujo, como la red. JDO permite que las clases extiendan tanto de java.io.Serializable como de javax.jdo.PersistenceCapable, sin embargo se debe tener en cuenta una consideración importante, consistente en que para que una instancia de JDO sea serializada debe ser primero desasociada de su PersistenceManager, lo cual se logra haciéndola transiente usando sus métodos makeTransient(Object o) o makeTransientAll(Collection c).. 23.
(24) <<interface>> java.io.Serializable. <<interface>> ClienteDTO. <<interface>> ReservaDTO. getCedula() getNombre() getTelefono().... getFecha() getTotal() getMulta() …. Cliente. *. Reserva. Figura 4. Utilización de clases del negocio como valueobjects. Una segunda consideración, proveniente del uso de java.io.Serializable, consiste en que al serializar un objeto se serializan junto con él todos los objetos serializables no transientes que sean alcanzables por él, lo que podría producir que se enviara por el flujo un grafo de objetos eventualmente grande. Una forma de solucionar este problema es definir estos atributos que referencian otros objetos como transientes, empleando el modificador transient de Java. Si se hace esto y se quiere sin embargo que el atributo sea persistente, se debe declarar el atributo como tal en el archivo XML de JDO. Por lo tanto, esta alternativa es viable para la transmisión de datos sin la necesidad de definir todo un nuevo grupo de clases, pero requiere de mucha atención por parte del desarrollador de la aplicación.. 3.3.3 Transacciones JDO ha sido diseñado para poder funcionar en ambientes manejados J2EE, siendo posible la interacción e integración de ambas especificaciones. Esto significa que en J2EE se pueden coordinar elementos como las transacciones y la seguridad entre componentes EJB y JDO, siendo estos controlados por el contenedor de aplicaciones. En caso de usar transacciones manejadas por el contenedor, no es necesario demarcar el inicio y fin de las transacciones de JDO dentro del código, ya que el contenedor se encargará de estas transacciones de manera similar a como lo hace con las de J2EE. Opcionalmente puede ser el Bean el responsable de manejar las transacciones, en cuyo caso es el desarrollador quien define programáticamente la forma de interactuar con las transacciones de ambos modelos, teniendo algunas consideraciones especiales para su uso (Core JDO, 2002) (Ross, 2003). Estas consideraciones consisten en el hecho de que si el objeto PersistenceManager es obtenido antes de que la transacción UserTransaction de J2EE se inicie, entonces los métodos begin, commit y rollback del objeto javax.jdo.Transaction pueden usarse, en caso contrario, solo pueden utilizarse los métodos del objeto UserTransaction.. 24.
(25) 3.3.4 JDOQL El uso de JDOQL dentro de JDO representa una de las características mas importantes y distintivas con respecto a otros APIs para el acceso a datos como JDBC. Lo primero y más importante consiste en que el lenguaje empleado sigue siendo Java, y no SQL como en el caso de JDBC. Esto significa que el desarrollador en principio no necesita conocer dos lenguajes con semántica y estructura distintas, sino que puede utilizar el mismo lenguaje para manipular los objetos en su código y para recuperarlos de una fuente de datos. Esto también facilita la portabilidad de la aplicación entre diversas tecnologías de persistencia de objetos. Es la implementación de JDO quien se encarga de traducir el lenguaje de JDOQL al lenguaje propio utilizado por la fuente de datos. Adicionalmente, y debido a que se ha eliminado la impedancia existente entre el modelo de objetos y el de datos, el código necesario para realizar tales funciones es mucho menor que el requerido en APIs como JDBC. Desafortunadamente, JDOQL es un lenguaje limitado para la recuperación de objetos. Este lenguaje permite solo la ejecución de consultas simples, la navegación de objetos a través de sus atributos, violando el encapsulamiento de los objetos, y la definición de filtros a partir de expresiones booleanas obtenidas usando los atributos de las clases y algunos métodos predefinidos en JDO. Este lenguaje tampoco cuenta con otras propiedades de lenguajes como OQL o SQL, incluyendo el manejo de proyecciones, funciones de agrupamiento o definición de vistas. Las razones anteriores pueden implicar que el desarrollador necesite realizar las consultas a partir de sus objetos en memoria, o bien complementar su aplicación con JDBC. Esta última alternativa no es recomendable teniendo en cuenta los inconvenientes mencionados anteriormente y que JDO pretende evitar, como que el desarrollador necesite tener un mayor conocimiento de la capa de datos y un entendimiento de dos lenguajes con esquemas distintos, y que necesite implementar una mayor cantidad de código para su uso. Además esta alternativa disminuye el mantenimiento y flexibilidad del aplicativo al requerir implementar un mayor número de cambios en la aplicación cuando la estructura de datos se modifica.. 3.4. Conclusiones. JDO presenta una solución más transparente al problema de la persistencia que la que se logra con los Entity Beans. No sólo reduce el nivel de conocimiento requerido por el desarrollador del sistema al presentar una interfaz uniforme y estándar, con el mismo modelo de objetos de Java, sino que produce una mayor independencia entre las clases del programa y la tecnología de persistencia que se implemente en los niveles de datos. Lo anterior beneficia el diseño, mantenimiento, tiempo de desarrollo y pruebas del sistema. Sin embargo, la solución no es completamente transparente. Por un lado, es necesaria la consideración o determinación de que clases y atributos deben persistirse, y tener presente las opciones y alternativas que la especificación y sus implementaciones ofrecen al. 25.
(26) momento de persistir sus objetos. Además, quien desarrolle la implementación del sistema debe tener un conocimiento del modelo y las decisiones de diseño de JDO, ser consciente de la persistencia por alcanzabilidad y del ciclo de vida de los objetos en este ambiente, con el fin de tener certeza de cual será el comportamiento de su aplicación al usar JDO, y poder utilizar efectivamente su API. Al utilizar JDO dentro de J2EE se logra integrar los servicios ofrecidos por ambas especificaciones, la posibilidad de tener una aplicación distribuida, transaccional y segura usando J2EE, y con un modelo de objetos persistente empleando JDO. Las consideraciones que se deben tomar en este caso corresponden a la estructura de la aplicación que resulta por su uso conjunto, incluyendo clases planas Java, componentes EJB como los Session Bean de fachada, y clases que interactúan con JDO. Se debe tener en cuenta el manejo de transacciones, y poder determinar cual es el mejor modelo para cada situación dada. También sigue siendo valido el uso de valueobjects como una manera de trasportar en pocos llamados remotos una cantidad relacionada de información. Finalmente, es claro que JDOQL no ofrece toda la potencia de lenguajes como SQL u OQL, lo que limita las posibilidades de recuperación y almacenamiento de datos. Estas limitaciones representan un obstáculo en la adopción de JDO por parte de desarrolladores, quienes no pueden resolver todas sus necesidades reales al respecto utilizando este lenguaje. Por esta razón es necesario un mayor trabajo sobre JDOQL en futuras versiones de la especificación JDO.. 26.
(27) 4. Diseño del modelo de persistencia para PSeneca. Como se mencionó inicialmente, el proyecto actual se encuentra enmarcado dentro de un proyecto de la Universidad de los Andes para el manejo de persistencia transparente de objetos denominado PSeneca (Abásolo, 2003). Otras alternativas existentes en este contexto han sido explicadas en capítulos anteriores, específicamente JDO y ODMG. Este capítulo muestra la propuesta de diseño de persistencia que ha sido utilizada para PSeneca, incluyendo la presentación de las características de diseño que están basadas en definiciones de las especificaciones ODMG y JDO y en los diseños de Craig Larman (Larman, 1997) y Scott Ambler (Ambler, 2000). También se presentan los puntos en los cuales PSeneca difiere de estas propuestas.. 4.1. Alcance. El alcance del proyecto dentro de PSeneca corresponde a los primeros servicios de los módulos del CCDL y el Adaptador. A continuación se describen los servicios implementados.. 4.1.1 Funcionalidad implementada en el CCDL • • • • • • • • •. Especificación de la interfaz al programador con los servicios de persistencia de objetos locales Especificación del lenguaje de consulta Especificación del modelo de objetos persistentes Especificación del archivo xml con la declaración de la persistencia Implementación de los servicios de persistencia y recuperación de objetos locales Implementación del manejo de ciclo de vida de los objetos persistentes Implementación de transacciones locales planas Definición de los servicios prestados por el adaptador Implementación de la arquitectura de conexión con el adaptador. 4.1.2 Funcionalidad implementada en el Adaptador • •. Implementación de los servicios de creación, actualización, eliminación y recuperación de objetos persistentes utilizando una fuente de datos relacional Implementación de la funcionalidad del lenguaje de consulta definida para el ciclo 1 para una fuente de datos de tipo relacional. 27.
(28) 4.2. Diseño Global. En esta sección se muestran los componentes principales de la aplicación, así como los conceptos y decisiones de diseño de un modelo persistencia transparente que fueron incorporados dentro de la solución. La Figura 5 muestra la arquitectura global de la implementación.. Figura 5. Diseño Global de la implementación de PSeneca. Los componentes principales de la aplicación, mostrados en laFigura 5, son:. 4.2.1 CCDL El contenedor de componentes de datos locales es el punto de entrada actual a la aplicación, y ofrece los servicios de persistencia transparente y consulta de objetos locales a una fuente de datos. No maneja ningún tema de distribución, que es una responsabilidad del CCCGD, y como este aún no se ha implementado, el CCDL no exporta el modelo de objetos al mismo. Sus principales componentes son:. 28.
(29) 4.2.1.1 PersistenceManager Interfaz principal de la aplicación, encargada del control del ciclo de vida de los objetos persistentes. El Persistence Manager ofrece servicios para persistir y recuperar objetos. Utiliza un cache para mantener objetos recuperados de la fuente de datos en memoria y permite la definición de transacciones locales planas. Utiliza la Metadata para realizar las operaciones que involucran interacción con la fuente de datos, como la creación, actualización, eliminación y recuperación de objetos. El nombre de PersistenceManager ha sido tomado de la especificación JDO (Rusell, 2002) al igual que algunos de los nombres de los métodos implementados. Su filosofía también es similar a la de JDO o a la de otros diseños, como el de Scott Ambler (Ambler, 2000) o Larman (Larman, 1997), en los cuales se conoce tal componente como un PersistenceBroker. Esta filosofía consiste en poseer un controlador principal que sea el encargado de la persistencia y recuperación de objetos de forma transparente, y de comunicarse con los demás elementos del sistema de persistencia que no son visibles al programador. Si bien la implementación realizada de PSeneca posee características similares a las de JDO, como la definición de un objeto persistente (PersistenceCapable en JDO) o el uso de un PersistenceManager y de estados para el control del ciclo de vida, tal implementación no es compatible con la especificación JDO 1.0 (Rusell, 2002).. 4.2.1.2 Query Interfaz que permite la definición y ejecución de consultas sobre objetos persistentes, en un lenguaje independiente de la fuente de datos. Dentro de los objetivos principales de PSeneca se encuentra la creación de un lenguaje declarativo de consulta de objetos denominado SenecaQL, similar en la medida de lo posible a OQL. La especificación del lenguaje de consulta desarrollada para PSeneca es por lo tanto muy similar a la especificación OQL de ODMG (ODMG, 1997), acomodándose en algunos sentidos a las características propias de Java, que también han sido definidas en el Java Binding de ODMG (ODMG, 1997). La interfaz Query y la clase QueryFactory definen toda la funcionalidad del lenguaje SenecaQL, en el cual las operaciones no se expresan en forma declarativa, sino a través de la invocación de métodos, de una manera muy cercana a la sintaxis Java. La interfaz OQLQuery, que se encuentra definida pero no implementada, es quien permite expresar la consulta de forma declarativa utilizando el lenguaje OQL (ODMG, 1997). Futuros desarrollos de PSeneca pueden implementar la interfaz OQLQuery y, posiblemente, traducir esta representación a la utilizada por la interfaz Query, proporcionando al desarrollador dos opciones para la expresión de consultas, como lo muestra en la Figura 6.. 29.
Documento similar
Para recibir todos los números de referencia en un solo correo electrónico, es necesario que las solicitudes estén cumplimentadas y sean todos los datos válidos, incluido el
La clave está en el hombre, en su actitud (recordemos de paso a Aris tóteles, y a algunos lingüistas, como Richards, para los cuales la literatura es productora de
La campaña ha consistido en la revisión del etiquetado e instrucciones de uso de todos los ter- mómetros digitales comunicados, así como de la documentación técnica adicional de
Para ello, trabajaremos con una colección de cartas redactadas desde allí, impresa en Évora en 1598 y otros documentos jesuitas: el Sumario de las cosas de Japón (1583),
Entre nosotros anda un escritor de cosas de filología, paisano de Costa, que no deja de tener ingenio y garbo; pero cuyas obras tienen de todo menos de ciencia, y aun
o Si dispone en su establecimiento de alguna silla de ruedas Jazz S50 o 708D cuyo nº de serie figura en el anexo 1 de esta nota informativa, consulte la nota de aviso de la
Las manifestaciones musicales y su organización institucional a lo largo de los siglos XVI al XVIII son aspectos poco conocidos de la cultura alicantina. Analizar el alcance y
A partir de un corpus múl- tiple (archivos del Instituto Nacional del Audiovisual (ina), prensa, litera- tura científica), este artículo regresa, primero, a ese momento discursivo y