1. Persistencia Hibernate
1.0 DEFINICION DE HIBERNATE los conocidos patrones para la delegación
de persistencia en POJOs.
Hibernate es una herramienta para la Una característica de la filosofía de diseño
plataforma Java que facilita el mapeo de de Hibernate ha de ser destacada
atributos entre una base de datos relacional especialmente, dada su gran importancia:
y el modelo de objetos de una aplicación, puede utilizar los objetos Java definidos por
mediante archivos declarativos (XML) que el usuario tal cual, es decir, no utiliza
permiten establecer estas relaciones. técnicas como generación de código a partir
Hibernate es una herramienta ORM de descriptores del modelos de datos o
completa que ha conseguido en un tiempo manipulación de bytecodes en tiempo de
record una excelente reputación en la compilación (técnica conocida por su
comunidad de desarrollo posicionándose amplio uso en JDO), ni obliga a
claramente como el producto OpenSource implementar interfaces determinados, ni
líder en este campo gracias a sus heredar de una superclase. Utiliza en vez de
prestaciones, buena documentación y ello el mecanismo de reflexión de Java,
estabilidad. Es valorado por muchos incluso característica que le permite un modelado
como solución superior a productos iterativo fluido y natural basado en UML,
comerciales dentro de su enfoque, siendo un factor fundamental para lograr un
una muestra clara de su reputación y trabajo ágil y productivo. Además abre las
soporte la reciente integración dentro del puertas a utilizar herencia en el modelo de
grupo JBoss que seguramente generará datos (esta opción estaría limitada si una
iniciativas muy interesantes para el uso de herramienta nos obliga a que los objetos de
Hibernate dentro de este servidor de datos hereden de una superclase por no
aplicaciones. soportar Java herencia múltiple).
Se empezó a desarrollar hace algo más de 2
años por Gavin King siendo hoy Gavin y Hibernate – Características
Christian Bauer los principales gestores de
su desarrollo. • No intrusivo (estilo POJO)
Hibernate parte de una filosofía de mapear • Muy buena documentación (forums
objetos Java "normales", también conocidos para ayuda, libro)
en la comunidad como "POJOs" (Plain Old • Comunidad activa con muchos usuarios
Java Objects), no contempla la posibilidad • Transacciones, caché, asociaciones,
de automatizar directamente la persistencia polimorfismo, herencia, lazy loading,
de Entity Beans tipo BMP (es decir, generar persistencia transitiva, estrategias de
automáticamente este tipo de objetos), fetching.
aunque aún así es posible combinar
Hibernate con este tipo de beans utilizando
1
2. Persistencia Hibernate
• Potente lenguaje de consulta (HQL): objetos en nuestra aplicación y en algún
subqueries, outer joins, ordering, momento queremos que sean persistentes,
proyeccion (report query), paginacion. normalmente abriremos una conexión
• Facil testeo. JDBC, crearemos una sentencia SQL y
• No es estandard. copiaremos todos los valores de las
propiedades sobre una PreparedStatement
o en la cadena SQL que estemos
¿Por qué necesitamos Hibernate?
construyendo. Esto podría ser fácil para un
objeto de tipo valor (value object:VO) de
pequeño tamaño pero consideremos esto
para un objeto con muchas propiedades.
Este no es el único problema. ¿Qué pasa
con las asociaciones? ¿Y si el objeto
contiene a su vez a otros objetos? ¿Los
almacenaremos también en la Base de
Datos? ¿Automáticamente? ¿Manualmente?
¿Qué haremos con las claves ajenas?
Preguntas similares surgen a la hora de
Si se esta trabajando con programación “cargar” un dato de la BD de un VO (se
orientada a objetos y bases de datos denomina value object o VO a un objeto
relacionales, seguramente habrás observado que contiene información de negocio
que estos son dos paradigmas diferentes. estructurada en grupos de ítems de datos,
El modelo relacional trata con relaciones, también recibe el nombre de transfer
tuplas y conjuntos y es muy matemático por object).
naturaleza. Sin embargo, el paradigma Como se puede ver, la brecha existente
orientado a objetos trata con objetos, sus entre los paradigmas de objeto y relacional
atributos y relaciones entre objetos. Cuando se vuelve mucho mayor si disponemos de
se quiere hacer que los objetos sean modelos con objetos “grandes”. Y hay
persistentes utilizando para ello una base de muchas más cosas a considerar como la
datos relacional, uno se da cuenta de que carga lenta, las referencias circulares, el
hay una desavenencia entre estos dos caché, etc. De hecho, hay estudios que
paradigmas, la también llamada diferencia demuestran que el 35% del código de una
objeto-relacional (object – relational gap”). aplicación se produce como consecuencia
Un mapeador objeto-relacional (ORM ) nos del mapeado (correspondencia) entre los
ayudará a evitar esta diferencia. datos de la aplicación y el almacén de
¿Cómo se manifiesta esta brecha entre datos.
ambos paradigmas? Si estamos utilizando
2
3. Persistencia Hibernate
Entonces, lo que necesitamos es una de la persistencia, como los Ejes de entidad,
herramienta ORM (Object Relational es que la clase Hibernate persistente puede
Mapping). Básicamente, una ORM intenta utilizarse en cualquier contexto de
hacer todas estas tareas pesadas por ejecución, es decir, no se necesita un
nosotros. Con una buena ORM, sólo contenedor especial para ello.
tendremos que definir la forma en la que
establecemos la correspondencia entre las Hibernate Query Language HQL
clases y las tablas una sola vez (indicando
que propiedad se corresponde con que Hibernate nos proporciona además un
columna, que clase con que tabla, etc.). lenguaje para el manejo de consultas a la
Después de esto, podremos hacer cosas base de datos.
como utilizar POJO’s (Plain Old Java Este lenguaje es similar a SQL y es
Objects) de nuestra aplicación y decirle a utilizado para obtener objetos de la base de
nuestra ORM que los haga persistentes, con datos según las condiciones especificadas
una instrucción similar a esta: en el HQL.
orm.save(myObject). Es decir, una El uso de HQL nos permite usar un
herramienta puede leer o escribir en la base lenguaje intermedio que según la base de
de datos utilizando VO’s directamente. datos que usemos y el dialecto que
Más formalmente: un modelo del dominio especifiquemos será traducido al SQL
representa las entidades del negocio dependiente de cada base de datos de forma
utilizadas en una aplicación Java. En una automática y transparente
arquitectura de sistemas por capas, el
modelo del dominio se utiliza para ejecutar Herramientas usadas junto con
la logica del negocio (en Java, no en la base Hibernate
de datos). Esta capa del negocio se
comunica con la capa de persistencia Existen diversas herramientas útiles para el
subyacente para recuperar y almacenar los uso de Hibernate que cubren todo el
objetos persistentes del modelo del desarrollo desde nuestra aplicación hasta
dominio. ORM es el middleware en la capa nuestra base de datos y viceversa:
de persistencia que gestiona la persistencia.
Hibernate es un ORM de libre distribución,
que además, es de las más maduras y
completas. Actualmente su uso esta muy
extendido y además esta siendo
desarrollada de forma muy activa. Una
característica muy importante que distingue
Hibernate de otras soluciones al problema
3
4. Persistencia Hibernate
rasgos al concepto de conexión de JDBC y
cumple un papel muy parecido, es decir,
sirve para delimitar una o varias
operaciones relacionadas dentro de un
proceso de negocio, demarcar una
transacción y aporta algunos servicios
adicionales como una caché de objetos para
evitar interacciones innecesarias contra la
BD. En este sentido veremos que la clase
Session ofrece métodos como save(Object
object), createQuery(String queryString),
Desde herramientas de modelado UML beginTransaction(), close(), etc. para
como por ejemplo con Poseidon podemos interactuar con la BD tal como estamos
generar modelos entidad relación que son acostumbrados a hacerlo con una conexión
traducidos por AndroMDA a POJO's y JDBC (de hecho "envuelve" una conexión
mediante XDoclet se generan los ficheros JDBC), pero con una diferencia: mayor
HBM. Todas estas tareas se automatizan simplicidad, es decir, guardar un objeto, por
mediante el uso de ANT. ejemplo, consiste en algo así como
session.save(miObjecto), sin necesidad de
Otra opción es crear la base de datos con
especificar una sentencia SQL, y esto es
una herramienta de modelado y a partir de
sólo un ejemplo muy trivial en el que
la base de datos una vez creada usar
ganamos relativamente poco utilizando
Middlegen para generar los ficheros HBM
Hibernate.
y a partir de estos los POJO's mediante
hbm2java Con esto volvemos a los conceptos de
transient y persistent: los primeros son
Los conceptos básicos de Hibernate objetos que sólo existen en memoria y no
en un almacén de datos (recuérdese en este
Hibernate se distingue entre objetos tipo sentido también el modificador transient de
transient y tipo persistent. Java), en algunos casos, no serán
Para almacenar y recuperar estos objetos de almacenados jamás en la base de datos y en
la base de datos, el desarrollador debe otros es un estado en el que se encuentran
mantener una conversación con el motor de hasta ser almacenados en ella. Los
Hibernate mediante un objeto especial, segundos se caracterizan por haber sido ya
quizás el concepto clave más importante almacenados y ser por tanto objetos
dentro Hibernate, que es la Sesión (clase persistentes. Dicho de otra: manera los
Session). Se puede equiparar a grandes objetos transient han sido instanciados por
4
5. Persistencia Hibernate
el desarrollador sin haberlos almacenado perteneciente a su correspondientes thread y
mediante una sesión, los objetos con su contexto de objetos en caché,
persistentes han sido creados y transacciones, etc. Como tal no sorprende
almacenados en una sesión o bien devueltos que las sesiones no son “thread-safe” y que
en una consulta realizada con la sesión. la información vinculada a ella no sea
visible para otras sesiones. Es también
Igual que con las conexiones JDBC hemos lógico que tenga que existir una
de crear y cerrar sesiones, aunque no hay “institución” superior para crear sesiones y
una relación 1:1 entre sesiones y realizar operaciones comunes a los
conexiones, es decir, no tenemos que abrir diferentes threads como lo puede ser la
y cerrar simultáneamente sesiones y gestión de una caché compartida entre
conexiones JDBC, la política a seguir threads o caché de segundo nivel. Este
dependerá del contexto del proceso de elemento es la clase SessionFactory y en
negocio de cada situación dándonos ella podremos encontrar métodos como
Hibernate amplias posibilidades para la openSession()o evict(Class persistentClass).
implementación de nuestras políticas Por fin tenemos que pensar también en qué
(conexiones JDBC gestionadas por la sucede si en un entorno de múltiples hilos
aplicación, por Hibernate, por un posible de ejecución la aplicación accede a un
servidor de aplicaciones, etc.), siendo mismo objeto desde dos sesiones diferentes.
solamente necesario en la práctica crear y Vimos que una instancia de un objeto
cerrar explícitamente las sesiones de persistente nunca es compartida por dos
Hibernate. sesiones al contar cada una con su propio
Hemos visto que las sesiones son un contexto para ello, de modo que existirán
concepto ligado a un proceso de negocio, dos instancias dentro de la misma máquina
por tanto es natural pensar que una sesión virtual Java para un “mismo” objeto de
siempre va a pertenecer a un mismo thread datos, lo cual no lleva al concepto de
de ejecución (el que pertenece a la identidad.
ejecución de un método de negocio para un Hay que distinguir entre identidad de
usuario o sistema externo concreto), aunque instancia Java, es decir: objeto1 == objeto2,
técnicamente se pueden compartir sesiones identidad persistente:
entre threads, esto no se debe hacer jamás objeto1.getId().equals(objeto2.getId)) y la
por no ser una buena política de diseño y identidad a nivel de base de datos (claves
los consecuentes problemas que puede primarias iguales). Por tanto, puede haber
generar. dentro de la misma máquina virtual varios
Es decir, en un entorno multiusuario y por objetos con la misma identidad persistente,
tanto multithread habrá por tanto múltiples pero diferentes identidades como instancias
sesiones simultáneas, cada una por ser objetos de datos Java que
5
6. Persistencia Hibernate
representan la misma entidad persistente. configurar Hibernate en un
Normalmente la identidad persistente del
entorno no gestionado, es
objeto y la identidad de base de datos
importante comprender la
coincidirán, pero esto puede no ser así para
lógicas de negocio muy particularidad. En diferencia entre la
todo caso, esta política depende del configuración de Hibernate
desarrollador que puede jugar, por ejemplo, para entornos gestionados y
con sobreescribir el método equals() para
no gestionados:
definir un comportamiento peculiar y
utilizar claves especiales para la identidad • Entorno gestionado: los pools de
de objetos diferenciándolas o recursos tales como
relacionándolas con la propiedad del objeto conexiones a la base de
utilizada como clave primaria para su
datos permiten establecer los
presistencia en la base de datos.
límites de las
Configuración de Hibernate transacciones y la
Para utilizar Hibernate en una aplicación, es seguridad se debe
necesario conocer como configurarlo. especificar de forma
Hibernate puede configurarse declarativa, es decir en sus
y ejecutarse en la mayoría de metadatos. Un servidor de
aplicaciones java y entornos aplicaciones J2EE, tal
de desarrollo. Generalmente, como JBoss, Bea
Hibernate se utiliza en WebLogic o IBM
aplicaciones cliente/servidor WebSphere implementan
de dos y tres capas, un entorno gestionado
desplegándose Hibernate para Java.
únicamente en el servidor. • Entorno no gestionado:
Las aplicaciones cliente proporciona una gestión
normalmente utilizan un básica de la concurrencia a
navegador Web, pero las través de un pooling de
aplicaciones swing y AWT threads. Un contenedor de
también son usuales. Aunque servlets, como Tomcat
solamente vamos a ver como proporciona un entorno de
6
7. Persistencia Hibernate
servidor no gestionado Configuración de la base de datos
para aplicaciones Web
Java. Una aplicación
stand-alone también se
considera como no
gestionada. Los entornos
no gestionados no
proporcionan
infraestructura para
transacciones
automáticas, gestiones de
Resumen de pasos de configuración
recursos, o seguridad. La
propia aplicación es la que
• Situar el *.jar del driver JDBC elegido
gestiona las conexiones
y el fichero hibernate2.jar en nuestro
con la base de datos y classpath
establece los límites de las • Añadir las dependencias de Hibernate
transacciones. (directorio (lib)) en el classpath.
Tanto en un entorno gestionado como en (lib/README.txt contiene una lista de
uno no gestionado, lo primero que debemos librerías requeridas y
hacer es iniciar Hibernate. Para hacer esto opcionales).
debemos crear una Session Factory desde
• Elegir y configurar un pool
una Configuration.
de conexiones JDBC
• Determinar las
propiedades de
Configuración en un
fichero
hibernate.properties en el
classpath,
• Crear una instancia de
Configuración en nuestra
7
8. Persistencia Hibernate
aplicación y cargar los - Session: interfaz primaria utilizada en
cualquier aplicación Hibernate
ficheros de mapeado XML
(SessionFactory).
utilizando addResource() o
- Transaction
addClass(). - Query: permite realizar peticiones a la
• Obtener una base de datos y controla cómo se
ejecuta dicha petición (query). Las
SessionFactory a partir de
peticiones se escriben en HQL o en el
Configuration llamando a
dialecto SQL nativo de la base de datos
BuildSessionFactory(). que estamos utilizando. Una instancia
Query se utiliza para enlazar los
2.0 ARQUITECTURA parámetros de la petición, limitar el
numero de resultados devueltos por la
El API de Hibernate es una arquitectura de petición y para ejecutar dicha petición.
dos capas (Capa de persistencia y Capa de • Interfaces llamadas por el código de la
Negocio). infraestructura de la aplicación para
En la siguiente Figura se muestran los roles configurar Hibernate. La más importante
de las interfaces Hibernate más importantes es la clase Configuration: se utiliza para
en las capas de persistencia y de negocio de configurar y "arrancar" Hibernate. La
una aplicación J2EE. La capa de negocio aplicación utiliza una instancia de
está situada sobre la capa de persistencia, Configuration para especificar la
debido a que actúa como un cliente de la ubicación de los documentos que indican
capa de persistencia. el mapeado de los objetos y propiedades
específicas de Hibernate, y a continuación
crea la Session Factory.
• Interfaces callback que permiten a la
aplicación reaccionar ante determinados
eventos que ocurren dentro de la
aplicación, tales como Interceptor,
Lifecycle, y Validatable.
• Interfaces que permiten extender las
funcionalidades de mapeado de
Las Interfaces mostradas se clasifican de la Hibernate, como por ejemplo UserType,
siguiente forma: CompositeUserType, e
• Interfaces llamadas por la aplicación para IdentifierGenerator.
realizar operaciones básicas: Además, Hibernate hace uso de APIs de
Java, tales como JDBC, JTA (Java
8
9. Persistencia Hibernate
Transaction Api) y JNDI (Java Naming administrativas que supone la
Directory Interface). celebración de un evento en la Feria de
Muestras de Valencia.
3.0 APLICACIÓN Además se pretende no solo simplificar
sino unificar y asegurar el
Prácticamente, no hay lugar donde el uso de cumplimiento de todas las tareas de
este framework no sea útil, las aplicaciones cada proceso de negocio.
Java que requieran una constante La intranet esta desarrollada con las
manipulación de base de datos requieren siguientes tecnologías:
por su facilidad de manejo y versatilidad
para los desarrolladores optar por Hibernate: motor de persistencia.
Hibernate. SQLServer 2000: base de datos
Si bien es cierto existe una brecha grande Struts y Tiles Ajax Servicios webs con Axis
entre los elementos que intervienen en el Servidor de aplicaciones JBoss
análisis y desarrollo de las aplicaciones de Diferentes patrones de diseño como
los proyectos que actualmente están Delegate, DAO, DTO, fachade, etc.
utilizando el paradigma orientados a
objetos, esto aun se ve aplazado por un
ancla el cual es la base de datos de tipo
relacional, sin embargo en la actualidad este
B. Desarrollo e implementación de
trabajo de conexión y manipulación de
aplicación comercial (ERP) en Web,
información de la base de datos ya no es tan
orientada a resolver la toma de
tediosa gracias a la aparición de Hibernate,
decisiones en todas las actividades de la
de la cual toda aplicación Web hecha en
empresa: Comercialización,
Java que necesite interactuar con la base de
Abastecimiento, Finanzas, Costos,
datos puede hacer uso, lo cual simplifica
Producción, Contabilidad,
enormemente la programación de lógica.
Presupuestos, Distribución, y control de
Gestión (administrativa, contable,
4.0 CASOS DE ÉXITO
presupuestaria, entre otras).
Tecnología Utilizada: Oracle Aplication
A. Adding Technology ha colaborado,
Server10g–iDS 10g–Oracle Server 10g.
por mediación de acuerdos firmados
con Soluziona, en el diseño y posterior
desarrollo de la intranet corporativa de
Feria de Muestras de Valencia. C. Bunge Argentina S.A
Se decide implantar un sistema que sea Workflow de usuarios: Desarrollo de
capaz de simplificar todas las tareas workflow para la gestión de usuarios y
9
10. Persistencia Hibernate
permisos de los diferentes ambientes de Hibernate podremos cubrir de manera
los sistemas de la organización sencilla y rápida el 80 - 90% de la
Workflow de Ajuste de Stock: persistencia de nuestra aplicación. Esto nos
Desarrollo de workflow para la gestión permite centrar nuestros esfuerzos en
de Ajustes de Stock y Transferencias en optimizar las consultas que realmente lo
y entre Plantas de productos merecen.
Tecnología Utilizada: Oracle9i - J2EE - * En cuanto al manejo de consultas
Hibernate - JBoss - Oracle Workflow. Hibernate saca una ligera ventaja ya que
tiene su propio lenguaje “HQL” que lo
hace multi – motor de base de datos, eso es
uno de los atractivos de Hibernate.
* Hibernate soporta la mayoría de los
5.0 CONCLUSIONES Y
sistemas de bases de datos SQL. El
RECOMENDACIONES
Hibernate Query Language, diseñado como
* Utilizar un framework de ORM una extensión mínima, orientada a objetos,
simplifica enormemente la programación de de SQL, proporciona un puente elegante
lógica de persistencia. Se trata de una idea entre los mundos objeto y relacional.
completamente madura que cada vez se Hibernate ofrece facilidades para
vuelve más popular. Nuestra lógica de recuperación y actualización de datos,
negocios trabaja contra un modelo de control de transacciones, repositorios de
dominio completamente orientado a conexiones a bases de datos, consultas
objetos. Generamos entre un 30% y un 40% programáticas y declarativas, y un control
menos de código y el tipo de código de relaciones de entidades declarativas.
generado es mucho más sencillo y * Hibernate es una muy buena herramienta
mantenible. en lo que se refiere a mapeo clases en una
* Es fundamental conocer bien como base de datos relacional, pero en lo que se
funcionan las tecnologías que utilizamos. refiere al manejo de transacciones y
En el caso de Hibernate hemos visto que conexiones le falta funcionalidad y
dependiendo de como hagamos las cosas capacidad.
puede afectar directamente al rendimiento
* Hibernate es menos invasivo que otros
de la aplicación.
marcos de trabajo de mapeo O/R. Se
Esto no quiere decir que no debamos usar
utilizan Reflection y la generación de
Hibernate, al contrario, Hibernate nos
bytecodes en tiempo de ejecución, y la
proporciona grandes beneficios como es la
generación del SQL ocurre en el momento
independencia de la base de datos, bajo
de la arrancada. Esto nos permite
acoplamiento entre negocio y persistencia,
desarrollar objetos persistentes siguiendo el
y un desarrollo rápido, ya que con
10
11. Persistencia Hibernate
lenguaje común de Java: incluyendo
asociación, herencia, polimorfismo,
composición y el marco de trabajo
Collections de Java.
11