Ingeniería inversa con Hibernate
Con Hibernate, la forma normal de trabajar es generar unos ficheros de extensión .hbm.xml en los que se define de alguna manera las tablas de base de datos, asociaciones entre ellas y los beans java asociados a dichas tablas. Luego, desde la aplicación java, usando hibernate y estos ficheros de configuración, se pueden crear automáticamente las tablas en la base de datos.
Puesto que esta es la forma normal de trabajar, se conoce como ingeniería inversa en Hibernate al proceso contrarios, es decir, a partir de las tablas ya creadas de base de datos, generar los ficheros .hbm.xml
Vamos a ver aquí cómo realizar este proceso.
¿Qué necesitamos?[edit]
Necesitamos, por supuesto, hibernate-core, que es lo básico de hibernate. También necesitamos middlegen, que son las herramientas hibernate-tools que permiten hacer la ingeniería inversa y otras transformaciones, como obtener los beans de java a partir de los .hbm.xml. Puesto que middlegen sólo corre con ant, también necesitaremos tener instalado ant. Además, necesitamos el driver de nuestra base de datos y un jar más que pide Hibernate, pero no distribuye: el velocity.jar.
- Hibernate-core se puede descargar de http://www.hibernate.org/6.html
- Middlegen o Hibernate-tools se puede descargar de http://sourceforge.net/project/showfiles.php?group_id=36044
- velocity.jar viene en su versión velocity-1.4-dev.jar dentro del directorio samples/lib de middlegen.
- Para el ejemplo, usaré un driver de mysql, que es la base de datos que tengo. Puedes encontrarlo en la página de mysql http://dev.mysql.com/downloads/connector/j/5.1.html
- ant te lo puedes descargar de http://ant.apache.org/bindownload.cgi
Empezamos a trabajar[edit]
Por supuesto, primero crea en mysql algunas tablas para poder jugar con ellas.
Ahora, en el directorio que queramos trabajar, debemos crear un fichero build.xml, que es el fichero que leerá ant. El fichero build.xml lo podemos crear con nuestro editor de textos favorito y se puede parecer a este
<project name="MyProject" default="middlegen" basedir="."> <!-- El classpath con el driver de la base de datos, hibernate y middlegen --> <path id="lib.class.path"> <pathelement location="/home/chuidiang/.m2/repository/mysql/mysql-connector-java/5.1.5/mysql-connector-java-5.1.5.jar" /> <pathelement location="/home/chuidiang/.m2/repository/velocity/velocity/1.4/velocity-1.4.jar" /> <pathelement location="/opt/hibernate-3.2/hibernate3.jar" /> <fileset dir="/opt/hibernate-3.2/lib"> <include name="*.jar" /> </fileset> <!-- The middlegen jars --> <fileset dir="/home/chuidiang/middlegen-2.1"> <include name="*.jar" /> </fileset> </path> <target name="middlegen"> <!-- Se define la tarea middlegen --> <taskdef name="middlegen" classname="middlegen.MiddlegenTask" classpathref="lib.class.path" /> <!-- parámetros para la tarea middlegen --> <!-- catalog es el nombre de la base de datos de la que queremos sacar las tablas --> <middlegen appname="prueba_hibernate" databaseurl="jdbc:mysql://localhost/" driver="org.gjt.mm.mysql.Driver" username="usuario" password="password" catalog="prueba"> <!-- Directorio de destino y paquete donde dejar los .hbm.xml --> <hibernate destination="src/main/config" package="com.chuidiang.beans" javaTypeMapper="middlegen.plugins.hibernate.HibernateJavaTypeMapper" /> </middlegen> </target> </project>
Así por encima, mencionaré un par de cosas
- En el tag <path> está indicado dónde están los jar necesarios. Los directorios que aparecen ahí son los mios. Tú tendrás que poner el path a donde los tengas. A este path, según el id que le hemos puesto, lo referenciaremos a partir de ahora como "lib.class.path".
- Al definir la tarea <taskdef name="middlegen"> hemos indicado el path con todos los jar.
- En el tag <middlegen> hemos puesto un nombre de aplicación -obligatorio- y los parámetros de conexión con nuestra base de datos. catalog es el nombre de la base de datos en concreto que queremos usar. Como no indicamos tablas, nos hará un fichero .hbm.xml por cada tabla, así que el proceso puede tardar un poco si tenemos muchas tablas.
- En el tag <hibernate> hemos puesto dónde queremos que nos cree los ficheros .hbm.xml.
Ahora solo queda ejecutar ant. Puesto que el fichero xml que acabamos de hacer se llama build.xml, que es el fichero por defecto que busca ant, símplemente tenemos que situarnos en el directorio donde esté el fichero build.xml y ejecutar ant. Tendremos una salida como la siguiente si todo va bien.
$ ant Buildfile: build.xml middlegen: [middlegen] log4j:WARN No appenders could be found for logger (middlegen.Middlegen). [middlegen] log4j:WARN Please initialize the log4j system properly. [middlegen] Database URL:jdbc:mysql://localhost/ [middlegen] No <table> elements specified. Reading all tables. This might take a while... [middlegen] Updated preferences in /home/chuidiang/.middlegen/prueba_hibernate-prefs.properties BUILD SUCCESSFUL Total time: 1 second
Y si todo va bien, en mi caso, he obtenido los siguientes ficheros .hbm.xml, correspondientes a las cuatro tablas que tenía creadas
$ find . -name *hbm.xml ./src/main/config/com/chuidiang/beans/Propietario.hbm.xml ./src/main/config/com/chuidiang/beans/Coche.hbm.xml ./src/main/config/com/chuidiang/beans/Prueba.hbm.xml ./src/main/config/com/chuidiang/beans/Persona.hbm.xml
El contenido de uno de los ficheros -son tablas sencillas, sin asociaciones-, es
$ cat ./src/main/config/com/chuidiang/beans/Propietario.hbm.xml <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > <hibernate-mapping> <!-- Created by the Middlegen Hibernate plugin 2.1 http://boss.bekk.no/boss/middlegen/ http://www.hibernate.org/ --> <class name="com.chuidiang.beans.Propietario" table="PROPIETARIO" > <id name="id" type="java.lang.Integer" column="ID" > <generator class="assigned" /> </id> <property name="fechaNacimiento" type="java.sql.Date" column="FECHA_NACIMIENTO" /> <property name="nombre" type="java.lang.String" column="NOMBRE" length="255" /> <!-- Associations --> </class> </hibernate-mapping>