Resumen del Proyecto Fin de Carrera 1. Motivación y contexto

Anuncio
Resumen del Proyecto Fin de Carrera
Alejandro Nogueiro Mariscal,
(1)
Juan Boubeta Puig, Antonio
Garcı́a Dominguez.
Calle Jacinto Benavente nº1 3ºD, CP 11100, San Fernando, Cádiz.
696 999 226, [email protected]
(1)
ESI I - E. Superior de Ingenierı́a
C/ Chile, 1
11002 Cádiz
Extracto
Este proyecto consiste en un generador de código para Hibernate desde
modelos UML. El código generado es el conjunto de clases del modelo
implementadas en Java con una serie de anotaciones JPA 2.0. Estas
clases, mediante Hibernate, sirven para añadir persistencia a nuestro
código. Los modelos UML tendrán una serie de anotaciones para poder
transformarlos correctamente.
Palabras Clave: hibernate, papyrus, uml.
1.
Motivación y contexto
1.1.
Introducción y motivación
Las bases de datos relacionales y los programas orientados a objetos organizan
la información de formas muy distintas. Las bases de datos relacionales tienden a
guardar datos escalares en las filas de una o más tablas, mientras que los programas
1
orientados a objetos operan con grafos de objetos en memoria. Esto genera una
serie de dificultades a la hora de cargar y guardar objetos en la base de datos, que
se conocen en conjunto como la “impedancia objeto/relacional”.
En los últimos años se han creado diversas bibliotecas para resolver este problema. Una de las más conocidas es Hibernate [1, 2, 3], una biblioteca de código
abierto bajo la licencia GNU Lesser General Public License(LGPL) disponible
para Java y .NET. Esta biblioteca puede integrarse con bases de datos de una
amplia variedad de tipos, incluyendo Oracle, Microsoft SQL Server, MySQL o
PostgreSQL, entre otras.
Hibernate es una biblioteca avanzada, con muchas funcionalidades. Por ello
se han creado herramientas de todo tipo para asistir a sus usuarios, ya sea para
depurar, desarrollar los programas, etc. Un problema común es la dificultad en
elaborar una primera versión de la correspondencia entre la base de datos y los
objetos Java. Esta tarea requiere escribir un fichero de configuración de cierta
complejidad, o escribir código Java con una mezcla de anotaciones propietarias de
Hibernate y otras de la especificación Java Persistence API 2.0 (JPA 2.0, JSR-317).
Por desgracia, las herramientas existentes para realizar esta tarea son en su
mayorı́a privativas y sus licencias pueden ser prohibitivas para desarrolladores individuales o empresas pequeñas. Las alternativas libres o no realizan dicha función
o son poco accesibles para nuevos usuarios, debido a su falta de usabilidad o la
baja calidad de su documentación.
En este Proyecto Fin de Carrera(PFC) se propone desarrollar un enfoque dirigido por modelos que ayude a escribir la versión inicial de los ficheros necesarios
para que Hibernate utilice una base de datos y genere el código Data Definition
Language(DDL) que define su estructura. Estos ficheros serán una series de clases
Java con anotaciones JPA 2.0. Para ello, se partirá de diagramas de clases UML
anotados mediante un perfil apropiado para bases de datos. Estos diagramas de
clases UML se validarán y transformarán a los ficheros oportunos mediante algunas
de las tecnologı́as disponibles actualmente.
2
1.2.
Objetivos
Este PFC pretende satisfacer los siguientes objetivos
Implementar transformaciones automatizadas de modelos UML a los artefactos necesarios para que Hibernate pueda acceder a las bases de datos
modeladas.
Validar los modelos UML comprobando que cumplen ciertas propiedades
deseables en una base de datos.
Proporcionar ayuda en diversos formatos al usuario, asistiéndole en su uso
cotidiano.
El PFC contará con una correcta documentación en español, con una guı́a que
detallará lo mejor posible la instalación y el uso del programa. La documentación,
además, estará disponible en lı́nea. Por otro lado, el PFC será publicado bajo
licencia libre. Además, pretende ser distribuido mediante una serie de extensiones
para uno de los entornos de desarrollo más populares.
2.
Planificación
En esta sección veremos cómo se ha organizado temporalmente el trabajo de
este proyecto ası́ como las tareas que han tenido lugar y la planificación de las
mismas.
En este proyecto se ha seguido el enfoque que promueve una metodologı́a de
desarrollo ágil de software, más concretamente, la programación extrema [4] o “eXtreme Programming”(XP) [5, 6], debido a la simplicidad de sus reglas y prácticas,
su orientación a equipos de desarrollo de pequeño tamaño y su flexibilidad ante
los cambios. La diferencia inmediata con otras metodologı́as es que se fija más
en mantener una comunicación con el usuario dı́a a dı́a, por lo que es necesaria
menos documentación que blinde a los desarrolladores. De muchas maneras son
3
más bien orientados al código: siguiendo un camino que dice la parte importante
de la documentación es el código fuente.
El desarrollo seguido se puede dividir en distintos apartados:
Aprendizaje de las tecnologı́as necesarias(27 de febrero al 9 de abril).
Pruebas y familiarización con el entorno de trabajo(16 de abril al 18 de
mayo).
Prueba de transformación a código Java de Hibernate(21 de mayo al 18 de
junio).
Primera Iteración(9 de julio al 16 de julio).
Segunda Iteración(del 16 al 23 de julio).
Tercera Iteración(del 23 al 30 de julio).
Cuarta Iteración(31 de julio al 7 de agosto).
Quinta Iteración(del 8 al 15 de agosto)
Sexta Iteración(1del 6 al 23 de agosto).
Séptima Iteración(del 24 al 31 de agosto).
Octava Iteración(del 3 al 10 de septiembre).
3.
Análisis
En esta sección hablaremos de las necesidades que debe cubrir el proyecto, es
decir, los requisitos que debe cumplir.
4
3.1.
Requisitos
En la realización de UML2Hibernate se pensaron en varios requisitos que deberı́a cumplir este proyecto. Para empezar, se estableció que el proyecto iba a
constar de una serie de extensiones para uno de los entornos de programación más
conocidos. En segundo lugar, se estableció que se iba a usar UML para los diagramas de clases a transformar debido a que es el estándar mas conocido y usado
para el diseño de modelos. En tercer lugar, establecimos las caracterı́sticas que se
modeları́an, como claves primarias, atributos no nulos, relaciones de asociación,
herencia, agregación y composición.
3.2.
Análisis de las Herramientas existentes
Antes de la realización de UML2Hibernate, tuvimos que realizar un exhaustivo
análisis de las herramientas que existı́an en el mercado que pudiesen hacer la
tarea que nosotros deseábamos realizar. Se analizaron principalmente AndroMDA
y Hibernate Tools. La primera se descartó debido a su dificultad de aprendizaje y
a su escasa documentación. La segunda se descarto debido a que no realizaba las
funciones deseadas.
3.3.
Cosas a modelar por UML2Hibernate
Los modelos UML a transformar deben poder contener los siguientes elementos,
necesarios para la correcta transformación a código para Hibernate.
Tablas. Si se desea crear una base de datos Objeto/Relacional, como es el caso, es
necesario disponer de tablas. Por ello UML2Hibernate debe poder modelar
Tablas para la base de datos.
Atributos. Aunque no hiciese falta aclararlo, una Tabla debe poder tener distintos atributos. Estos atributos deberán disponer de un tipo para su correcta
transformación en código. Debido a que las clases generadas para Hibernate
5
se generan en código Java con una serie de anotaciones, los tipos serán los
tipos de Java más el tipo Date(también de Java), tipo muy común en las
Bases de Datos.
Claves Primarias simples. Si se dispone de Tablas, es fundamental disponer de
Claves Primarias para las mismas, ya que toda tabla debe tener una clave
primaria.
Atributos no nulos y de valor único. Estos tipos de atributos también son
frecuentes en el diseño de una base de datos, por lo que serı́a deseable que
UML2Hibernate pudiese tratarlos.
Atributos de tipo vector. En muchas bases de datos, se usan atributos que son
una lista de distintos atributos, como por ejemplo si se quisiera tener una
lista de teléfonos para cada empleado. Es por ello por lo que UML2Hibernate
debe modelar este tipo especial de atributos.
Herencia. En las Bases de Datos Objeto/Relacionales la herencia es un recurso
muy usado, por ello UML2Hibernate debe poder tratarlo.
Asociaciones binarias. Es fundamental en una Base de Datos que las tablas
estén relacionadas entre sı́, por ello UML2Hibernate debe poder tratar las
asociaciones entre dos tablas, ası́ como la composición y la agregación.
4.
Perfil UML
En este capı́tulo hablaremos de la creación del perfil UML usado en este pro-
yecto.
4.1.
Definición del Perfil UML
Para poder modelar diagramas de clases que se puedan transformar en código
para Hibernate sin ninguna información adicional, es necesario un perfil que defina
6
las anotaciones necesarias para la definición de una base de datos.Para ello se encontró un perfil de una tesis [7] para el diseño de bases de datos en UML. La autora
de esta tesis es Elisa Martı́nez Real y su tı́tulo es “Extensión de una herramienta
CASE para la traducción de esquemas conceptuales en UML a esquemas lógicos
en UML Data Modeling Profile”. El proyecto consistı́a en desarrollar una nueva
funcionalidad CASE que permita desarrollar un esquema conceptual y que genere
automáticamente el esquema lógico y su posterior transformación a código SQL
estándar y a código especı́fico del Sistema de gestión de bases de datos(SGBD).
Debido a que este perfil era más amplio de lo que necesitabamos, se decidió crear
un perfil UML con un subconjunto de los componentes de ese perfil, de tal manera
que tuviésemos sólo las anotaciones necesarias. A continuación se expone el perfil
UML(figura 1) y se explica brevemente cada uno de sus elementos.
Figura 1: Perfil UML de UML2Hibernate construido con Papyrus
Table. Para poder modelar las tablas, se ha creado un Estereotipo de la Metaclase
7
“Class” llamado “Table”. Ası́ se distinguirán las clases que son tabla de las
que no.
PK. Para poder modelar las claves primarias, se ha creado un Estereotipo de la
Metaclase “Property” llamado “PK”. Ası́ se distinguirán los atributos que
son clave primaria de los que no.
Unique. Para poder modelar los atributos de valor único, se ha creado un Estereotipo de la Metaclase “Property” llamado “Unique”. Ası́ se distinguirán
los atributos de valor único.
NotNull. Para poder modelar los atributos de valor no nulo, se ha creado un
Estereotipo de la Metaclase “Property” llamado “NotNull”.
Date. Debido a que en los tipos primitivos de Java para los modelos UML de
Papyrus no está definido el tipo “Date”, se ha tenido que definir un tipo
primitivo para poder modelar los atributos de este tipo.
4.2.
Implementación del Perfil UML
En la creación del perfil, se crean dos tipos distintos de perfil: uno dinámico y
uno estático. Un perfil dinámico de Papyrus define su metamodelo cada vez que
se usa, es decir, define su metamodelo en el instante en el que es usado y de forma
temporal. Un perfil estático, en cambio, tiene asociado un metamodelo de Ecore de
forma permanente, generando las clases Java necesarias para ello. Pasemos ahora
al proceso de creación del perfil UML. Para la creación del perfil dinámico, simplemente se crea un perfil de UML mediante Papyrus y se le añaden los tipos básicos
de Java. Para la creación del perfil estático de UML hemos usado la herramienta de
Ecore para generar metamodelos, un archivo de extensión “.genmodel”. A partir
de él se ha generado la estructura necesaria para poder crear el perfil estático.
8
5.
Generación de Código para Hibernate y
Pruebas
En este punto hablaremos sobre la estructura general de la validación y trans-
formación a código del modelo, y de las pruebas realizadas.
5.1.
Generación de código para Hibernate
Para la generación del código para Hibernate se ha implementado un programa
EGL. A continuación vamos a exponer su estructura pincipal.
Creación de la Clase. Es la estructura principal del programa EGL. Aquı́ se
escribira la estructura principal de la clase, incluyendo los “include”. Se compone
de dos módulos:
Atributos. En este módulo se escribirán los distintos atributos de la clase. Este
módulo se divide a su vez en distintos submódulos. Estos módulos son los
siguientes:
Claves Primarias. En este submódulo se tratarán los atributos que son
clave primaria.
Asociaciones. En este submódulo se tratarán los atributos procedentes de
una asociacion, composición o agregación.
Resto de Atributos. En este submódulo se tratan el resto de atributos,
es decir, atributos simples, no nulos o de valor único.
Métodos “get”‘y “set”. En este módulo se crearán los métodos “get” y “set”
para todos los atributos de la clase.
5.2.
Validación del modelo
Para comprobar que el modelo a transformar es válido antes de transformarlo,
se ha implementado un programa EVL para validar el modelo. Este programa EVL
9
se compone de los módulos expuestos a continuación.
Módulo de comprobación de las Clases. En este módulo se comprueba que
las clases sean correctas. Para ello se definirán las siguientes pruebas:
Toda clase posee nombre.
Toda clase es Tabla.
Todos los atributos de la clase son correctos.
Toda clase tiene clave primaria.
Módulo de comprobación de los Atributos. En este módulo se comprueba
que todos los atributos son correctos. Para ello se definirán las siguientes
pruebas:
Todo atributo posee nombre.
Todo atributo tiene tipo.
El tipo de todo atributo es válido, es decir, es un tipo de Java.
5.3.
Pruebas
Para probar el correcto funcionamiento de las clases generadas, se han creado
una serie de pruebas unitarias integradas en un proyecto de Maven [8]. Para ello,
hemos generado el código para un diagrama de clases UML con las anotaciones del
perfil anteriormente expuesto. Además, para demostrar que las clases generadas
por UML2Hibernate son las esperadas, se dispone de una prueba unitaria que
comprueba que las clases con las que se hacen las pruebas unitarias y las que
generarı́a el programa son las mismas. Se ha tenido que hacer de esta manera, ya
que es bastante complicado integrar en un proyecto Maven(en el cual realizamos
las pruebas) un conjunto de clases directamente generado por el programa. Para
la realización de las pruebas se ha usado EUnit [9] y JUnit [10].
10
Además de este proyecto Maven, se dispone de otro proyecto de pruebas para
comprobar que se valida correctamente los modelos antes de transformarlos. Por
ello, se ha creado un proyecto con una serie de pruebas que testean el correcto
funcionamiento de la validación. Para este proyecto, unicamente se usan pruebas
unitarias del lenguaje EUnit.
6.
Conclusiones
6.1.
Resultados obtenidos
En este proyecto se han desarrollado una serie de plugins para Eclipse para
poder transformar modelos de UML, que representan una base de datos, en código
para Hibernate. Para esto, se ha tenido que cumplir una serie de requisitos, que
exponemos a continuación.
Implementa transformaciones automatizadas de modelos UML a los artefactos necesarios para que Hibernate pueda acceder a las bases de datos
modeladas. UML2Hibernate posee un perfil UML con varias anotaciones
para poder cumplir este requisito. Existen las anotaciones para distinguir
tablas, claves primarias, atributos no nulos y atributos con valor único. Con
estas anotaciones se puede transformar correctamente el modelo en código
para Hibernate.
Valida los modelos UML comprobando que cumplen ciertas propiedades
deseables en una base de datos. La validación se encarga de comprobar que
los modelos son válidos para la transformación a código para Hibernate, pro
ello hace comprobaciones tales como que toda tabla posee clave primaria.
Proporciona ayuda en diversos formatos al usuario, asistiéndole en su uso
cotidiano. En este proyecto era muy importante la documentación para el
uso de la herramienta. Es por ello que se ha realizado un completo manual de
11
usuario en español y una wiki con la documentación en inglés, varios vı́deos
ilustrativos de cómo se usa UML2Hibernate y varios ejemplos de modelos
ya realizados con UML2- Hibernate.
Con estos requisitos, se han cumplido todos los objetivos propuestos inicialmente para este proyecto.
6.2.
Valoración personal
La realización de este proyecto fin de carrera ha sido muy interesante, pues me
ha permitido conocer una cantidad considerable de nuevas técnicas, lenguajes de
programación y aplicaciones; además me ha servido para conocer cómo se trabaja
en un proyecto de mayor envergadura que los que se han hecho en la Ingenierı́a
Técnica. La realización de UML2Hibernate ha sido muy compleja, porque además
de la programación se ha tenido que trabajar con un programa concreto(Eclipse)
e introducir mi herramienta en el, he tenido que desarrollar un documento técnico
pro primera vez, y además he tenido que crear manuales para el usuario en varios
formatos poniéndome en el lugar del que no conoce mi herramienta.
Antes de este proyecto sólo conocı́a el lenguaje de programación C++, por lo
que hubo una fase de aprendizaje. Los lenguajes EGL y EVL de Epsilon no poseen
una estructura similar a C++, pero no son lenguajes para nada complicados y no
me costo mucho aprenderlos. En cuanto a Java, su sintaxis es similar a C++,
pero los problemas surgidos a Java no tienen nada que ver con el lenguaje, sino
con la inclusión del proyecto en el entorno de trabajo de Eclipse. En esta fase de
aprendizaje, además, tuve que aprender conceptos sobre Ingenierı́a Dirigida por
Modelos, puesto que en la Ingenierı́a Técnica no se habla nada sobre ello.
Para la inclusión de UML2Hibernate en el entorno de Eclipse y Papyrus se ha
tenido que indagar bastante en código fuente de estas herramientas. Para añadir
una pequeña entrada en un menú, por ejemplo, habı́a que ir mirando que plugin implementaba el menú, acceder al código fuente, ver la clase que finalmente
12
implementaba el menú y finalmente quedarse con ella para implementar el punto
de extensión. Es por ello que, en este proyecto, he aprendido bastante a entender
código fuente, y sobre todo, a encontrar y solucionar los numerosos problemas que
salen al crear plugins para Eclipse.
Por primera vez, se ha tenido la oportunidad de aplicar un diseño iterativo,
y comprobar su gran utilidad en proyectos en los que no se tienen claro desde el
principio todos los requisitos que deben cumplir. Se ha aplicado este proceso hasta
conseguir que la aplicación cumpliera con los requisitos esperados.
Para el control de versiones se ha usado Git. Gracias a este proyecto he conocido
esta herramienta, puesto que en el pasado sólo habı́a usado Subversion. EL código
fuente del proyecto, y por tanto cada una de sus modificaciones, se ha subido a la
forja del grupo UCASE.
En cuanto a la colaboración con el grupo UCASE, decir que ha sido la primera
vez que he participado en un grupo de investigación. Prácticamente todas las
semanas habı́a una reunión en la que se podı́a exponer las dudas y problemas
que iban surgiendo a lo largo del desarrollo. Estas reuniones me han servido para
aprender conceptos ajenos a mi proyecto unas veces, y otras veces relativos a mi
proyecto. En ambos casos ha sido de utilidad, puesto que nunca viene de más
conocer más tecnologı́as.
Uno de los seminarios más útiles en la realización de mi proyecto fue uno
en el que se explicó como desarrollar un plugin de Eclipse y un Update Site. A
pesar de que al realizarlo muchas cosas eran para nada parecidas, me sirvió como
conocimiento previo para no empezar de cero.
En cuanto a las pruebas unitarias, eran un requisito adicional que se habı́a
incluido con el fin de mejorar la calidad del producto resultante y darle mayor
dimensión al proyecto. Además, como se usa la metodologı́a “eXtreme Programing”
estas pruebas forman parte del desarrollo de software. Era la primera vez que usaba
este tipo de pruebas de software, ya que en la Ingenierı́a Técnica no desarrollamos
pruebas de este tipo. Como habı́a que probar distintas cosas, se realizaron dos
13
proyectos de pruebas, uno para probar la validación y otro para probar que el
código generado funcionase correctamente. En las pruebas de validación se usa
EUnit, puesto que sólo se probaba un programa en EVL con diversos modelos.
En las pruebas del código generado se usa tanto EUnit como JUnit, puesto que
hay que demostrar que las clases del proyecto son iguales a las que se generarı́an,
y luego demostrar que estas clases Java con anotaciones de Hibernate funcionan
correctamente.
Para concluir, queda destacar que este proyecto me ha enseñado, aparte de las
diversas tecnologı́as aprendidas, a “buscarme la vida” solucionando errores en los
que tenı́a que leer bastante código fuente no escrito por mi, por lo que he aprendido
bastante a entender código fuente de otros programadores.
6.3.
Trabajo futuro
Como trabajo futuro se pueden añadir elementos de las bases de datos más
complejos y difı́ciles de implementar su transformación, como es el caso de asociaciones n-arias, claves primarias compuestas o lanzadores(triggers). En cuanto a
la transformación en sı́, se podrı́a dar la opción de transformar el modelo, en vez
de a código Java, a código HEDL [11, 12](Hibernate Entity Definition Language).
Es un lenguaje de fecha de creación muy cercana(febrero de 2012) que sirve para
generar código para Hibernate.
En futuras versiones, se implementará la corrección automática, para que el
usuario no tenga que corregir los errores cometidos en el modelo.
Referencias
[1] JBoss Inc. Hibernate.
[2] D. Minter y J. Linwood. Beginning Hibernate: From Novice to Professional.
Apress, primera edición, agosto 2006. ISBN 1590596935.
14
[3] G. Mak y S. Guruzu.
Hibernate Recipes: A Problem-Solution Approach.
Apress, primera edición, junio 2010. ISBN 1430227966.
[4] K. Beck. Programacion extrema.
URL http://www.programacionextrema.org/
[5] K. Beck. Extreme programming: A gentle introduction.
URL http://www.extremeprogramming.org/
[6] K. Beck. Extreme Programming Explained: Embrace Change. Addison-Wesley
Professional, US ed edición, octubre 1999. ISBN 0201616416.
[7] E. Martı́nez Real. Extensión de una herramienta case para la traducción
de esquemas conceptuales en uml a esquemas lógicos en uml data modeling
profile. septiembre 2008.
URL http://upcommons.upc.edu/pfc/handle/2099.1/5385
[8] J. van Zyl. Maven.
URL http://maven.apache.org/
[9] Eclipse Foundation. Epsilon unit testing framework.
URL http://www.eclipse.org/epsilon/doc/eunit/
[10] E. Gamma y K. Beck. JUnit.org.
URL http://www.junit.org/
[11] DevBoost. HEDL.
URL http://www.hibernate-dsl.org/index.php/HEDL
[12] DevBoost. HEDL en eclipse.
URL
http://marketplace.eclipse.org/content/
hedl-hibernate-entity-definition-language#.UFFr1mbI9Bl
15
Descargar