Narciso, Hablando de Software

13.8.04

Hibernate y JBoss

Lo prometido es deuda, así que hoy voy a explicar cómo he integrado Hibernate y JBoss.
Lo primero que hay que tener en cuenta son las versiones, esto aplica a JBoss 3.2.x (en concreto estoy trabajando actualmente con la 3.2.5) y a Hibernate 2.1.6. La versión 2.1.4 de Hibernate tenía un fallo que impedía su uso con JBoss así que es imporante utilizar la 2.1.6 que ahora es la última disponible.
Al grano.
Con Hibernate creamos los denominados POJO (Plain Old Java Objects) o Java Beans, e Hibernate se encarga de manejar la persistencia de dichos objetos. Hibernate nos permite una flexibilidad increiblemente mayor que los Entity Beans a la hora de diseñar la estructura de clases, y eso significa que podemos hacer diseños de una granularidad muy fina, usar la herencia adecuadamente y crear componentes (otros POJOs) que actúen como campos de nuestras entidades.
Para hacer que Hibernate funcione con JBoss hemos de crear un archivo de servicio dentro de nuestra aplicación, es decir un archivo .SAR, pero como queremos poder llamar a nuestras clases desde el resto de la aplicación, en dicho .SAR sólo irá el archivo de servicio y los archivos descriptores de nuestras entidades (los .hbm.xml). Y algo más... también hemos de incluir el archivo de servicio que creará la fuente de datos (DataSource) uitilizado por Hibernate.
Yo utilizo XDoclet y Ant para la automatización de todo este proceso, aunque XDoclet introduce algunas limitaciones sigue siendo lo suficientemente interesante.
Por otro lado, en nuestro archivo de aplicación (.EAR) tenemos que hacer referencia a los diferentes servicios en el orden adecuado, así como incluir todas las librerías necesarias: las que necesita Hibernate, una con las clases que representan nuestras entidades y el resto que necesite nuestra aplicación.
En definitiva, nuestra aplicación debe tener la siguiente estructura:
aplicacion.EAR
|
|- hibernate.SAR
| |
| |- descriptores
| |- META-INF/
| |
| |- datasource.xml
| |- jboss-service.xml
|- lib/
| |- dependencias de Hibernate
| |- model.jar
| |- demás librerías que necesite la aplicación
|
|- META-INF/
| |
| |- application.xml
| |- jboss-app.xml

Dónde:

  • descriptores es la jerarquía de directorios paralela a nuestra jerearquía de clases persistentes con los ficheros .hbm.xml correspondientes

  • datasource.xml es el descriptor de nuestro origen de datos (más información en la documentación de JBoss)

  • jboss-service.xml es el descriptor del servicio Hibernate. Yo lo genero automáticamente con Ant y XDoclet, es lo más cómodo y seguro para no equivocarse. En cualquier caso os doy un ejemplo

  • model.jar es nuestro modelo, las clases persistentes que manejará Hibernate empaquetadas en un jar.

  • application.xml es el descriptor de aplicación J2EE (más información en la documentación de Java J2EE). Aquí lo importante es hacer referencia a todas las librerías y servicios de nuestra aplicación, así que también os pongo un ejemplo.

  • jboss-app.xml es el descriptor de aplicación específico de JBoss, en el se hace referencia al servicio de Hibernate y a otros que podamos tener en nuestra aplicación (más información en la documentación de JBoss). También os doy otro ejemplo


Ejemplos:
1. Archivo de servicio para hibernate.SAR

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE server>
<!-- Generated file - Do not edit! -->

<server>
<mbean
code="net.sf.hibernate.jmx.HibernateService"
name="jboss.jca:service=Model"
>
<depends>jboss.jca:service=RARDeployer</depends>
<attribute name="MapResources">
com/sample/app/model/Role.hbm.xml,
com/sample/app/model/common/Telephone.hbm.xml,
(other descriptors)
</attribute>
<attribute
name="JndiName"
>java:/hibernate/DefaultSessionFactory
</attribute>
<attribute
name="Datasource">java:/myDS</attribute>
<attribute
name="Dialect">net.sf.hibernate.dialect.MyDialect
</attribute>
<attribute
name="ShowSql">false</attribute>
<attribute
name="UserTransactionName">UserTransaction
</attribute>
<attribute
name="TransactionStrategy"
>net.sf.hibernate.transaction.JTATransactionFactory
</attribute>
<attribute
name="TransactionManagerLookupStrategy"
>
net.sf.hibernate.transaction.JBossTransactionManagerLookup
</attribute>
</mbean>
</server>


2. Archivo de aplicación

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE application
PUBLIC '-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN'
'http://java.sun.com/dtd/application_1_3.dtd'>
<application>
<display-name>Mi Aplicación</display-name>

<!-- ===================================
jdbc driver
======================================= -->
<module>
<java>lib/my-jdbc-driver.jar</java>
</module>

<!-- ===================================
Model classes
======================================= -->
<module>
<java>lib/model.jar</java>
</module>

<!-- ===================================
Hibernate classes
======================================= -->
<module>
<java>lib/c3p0-0.8.4.5.jar</java>
</module>
<module>
<java>lib/cglib-full-2.0.2.jar</java>
</module>
<module>
<java>lib/commons-collections-2.1.1.jar</java>
</module>
<module>
<java>lib/commons-lang-1.0.1.jar</java>
</module>
<module>
<java>lib/concurrent-1.3.3.jar</java>
</module>
<module>
<java>lib/dom4j-1.4.jar</java>
</module>
<module>
<java>lib/ehcache-0.9.jar</java>
</module>
<module>
<java>lib/hibernate2.jar</java>
</module>
<module>
<java>lib/jaas.jar</java>
</module>
<module>
<java>lib/jcs-1.0-dev.jar</java>
</module>
<module>
<java>lib/odmg-3.0.jar</java>
</module>
<module>
<java>lib/oscache-2.0.jar</java>
</module>
<module>
<java>lib/swarmcache-1.0rc2.jar</java>
</module>

<!-- ================================
EJBs
===================================== -->
<module>
<ejb>ejbs/01-model.jar</ejb>
</module>

<!-- ================================
Web Application
===================================== -->
<module>
<web>
<web-uri>my.war</web-uri>
<context-root>/my</context-root>
</web>
</module>
</application>

3. Archivo de aplicación de JBoss

<jboss-app>

<module>
<service>model.sar</service>
</module>

</jboss-app>


Y con esto terminamos por hoy. Con estas instrucciones no deberías tener problemas para empezar rápidamente con Hibernate y JBoss, sobretodo si utilizais Ant y XDoclet, lo cual os aconsejo.