jueves, 8 de septiembre de 2016

Hibernate ORM Introducción

Introducción
Toda aplicación llega un momento en el que tiene que recolectar, procesar, transformar y guardar
una cantidad considerable de datos, se guarda en algún lugar y que perdure con el tiempo.
En el mundo Java se ha hecho un gran esfuerzo por simplificar y reducir el tiempo del proceso de desarrollo en la lectura y escritura de datos entre una aplicación y una base de datos.
Primero surgió la tecnología JDBC y últimamente la tecnología JPA, antes de adentrarnos a lo que es JPA debemos conocer el concepto ORM e Hibernate.

¿Qué es persistencia?
Como mencioné al inicio, casi todas las aplicaciones requieren datos persistentes(que duren en el tiempo) . La persistencia es un concepto fundamental en el desarrollo de aplicaciones. Si un sistema de información no permite conservar los datos cuando este se cierra o cuando el computador se apaga, entonces el sistema sería de poca utilidad práctica .
Cuando hablamos acerca de la persistencia en Java, normalmente estamos hablando de almacenamiento de datos en una base de datos relacional utilizando SQL, no necesariamente pero si en su mayoría, ya que igual podemos persistir datos en archivos xml o archivos planos.

Bases de datos relacionales
Las bases de datos nacieron hace muchos años como un medio o tecnología para almacenar datos, con el tiempo han evolucionado y hoy suenan otras tecnologías cómo: almacenamiento en la nube, Big Data y NoSQL.
Pero aun así las bases de datos relacionales siguen siendo las más usadas, ya que son de propósitos generales.
No sé con certeza que porcentaje de las aplicaciones Java usen base de datos relacionales como tecnología de almacenamiento de datos, pero al menos en mi vida laboral, siempre las hemos usado. En la web puedes encontrar información más extensa sobre base de datos relacionales.

ORM Object-Relational Mapping (Mapeo Objeto Relacional)
En Java tenemos como nuestro elemento básico una clase, el cual tiene un conjunto de atributos(variables de instancia de la clase) y cada atributo un tipo de dato. La base de datos relacional tiene una tabla con un conjunto de columnas y cada columna un tipo de dato. Se ven bastante similares. Debe ser simple para convertir una a la otra de forma automática. Este es un pensamiento que probablemente todos hemos tenido en un momento u otro mientras escribimos un DAO(Objeto de Acceso a Datos) para convertir los resultados de una consulta JDBC (Java Database Connectivity)  en algo orientado a objetos. El modelo de clases parece bastante similar al modelo relacional de la base de datos que parece pedir una forma de hacer que los dos modelos se comuniquen entre sí.

En pocas palabras, el  mapeo objeto-relacional es la persistencia de objetos de una aplicación Java a las tablas de una base de datos relacional de forma automatizada (y transparente), utilizando metadatos que describe la correlación entre los objetos y la base de datos .
ORM, en esencia, transformar datos de una representación a otra y viceverza. es decir de objetos a tablas y de tablas a objetos. Este proceso implica ciertas penalizaciones de rendimiento que por ahora ignoraremos.

Una solución ORM consta de las siguientes cuatro piezas :
  1. Una API para realizar operaciones básicas CRUD sobre los objetos de las clases persistentes
  2. Un lenguaje o API para especificar consultas que se refieren a las clases y sus atributos.
  3. Una instalación para especificar metadatos de mapeo
  4. Una técnica para la aplicación ORM para interactuar con objetos transaccionales y para llevar a cabo la ejecución de los objetos manipulados, carga de datos a demanda, y otras funciones de optimización

Antes de entrar en los detalles de mapeo objeto-relacional, vamos a definir un breve manifiesto de lo que la solución ideal debe ser.

• Objetos, no tablas: Las aplicaciones deben ser escritas en términos del modelo de objetos, sin estar ligado al modelo relacional. Debería ser posible operar sobre el modelo de objetos sin tener que expresarlo en el lenguaje relacional de tablas, columnas, y las claves externas.

• Comodidad, no ignorancia: Las herramientas de mapeo deben ser utilizadas sólo por personas con amplia experiencia en la tecnología relacional. ORM no está destinado a ser una solución para aquellos desarrolladores novatos que no tienen idea de la tecnología relacionales.  Está dirigido para aquellos que tienen una comprensión de los problemas que enfrentan y saben lo que necesitan, pero que no quieren tener que escribir miles de líneas de código para hacer frente a un problema que ya ha sido resuelto.

• Discreto, no es transparente: Es razonable esperar que la persistencia sea transparente
porque una aplicación siempre necesita tener el control de los objetos que persiste y
ser consciente del ciclo de vida de la entidad. La solución de ORM no debe entrometerse en el dominio del negocio, es más, las clases del  dominio del negocio no están obligados a extender clases o implementar interfaces que imponga la solución ORM.

• Base de datos ya existente, nuevos objetos: Es mucho más probable que una aplicación se integrará a una base de datos ya existente que a una base de datos nueva. El soporte a base de datos ya existentes (Legacy) es un caso muy común al que nos enfrentaremos y una buena herramienta ORM está preparado para ello.

• Suficiente, pero no demasiado: Los desarrolladores de aplicaciones tienen problemas que resolver, y que necesitan características suficientes para resolver esos problemas. No necesitamos un ORM muy poderoso pero a la vez complicado de usar, si no, luego sale más caro el remedio que el problema.

• Local, pero móvil: Una representación persistente de datos no necesita ser modelado como un conjunto de objetos totalmente remoto. La distribución es algo que existe como parte de la aplicación, no como parte de la capa de persistencia. Las entidades(objetos) que son persistentes, sin embargo, deben ser capaz de viajar con cualquier capa que necesite estar en una aplicación distribuida.

• API estándar, con implementaciones compatibles: Las grandes empresas con aplicaciones de tamaño considerable no quieren arriesgarse a estar amarrados a bibliotecas e interfaces específicas de un producto. Ellos quieren depender de interfaces estándares y bien definidos, que su aplicación esté desacoplada de APIs propietarios y cambiar fácilmente a otro producto o solución ORM si esté es más adecuado.
Esto parece ser un poco exigente, pero la practica y la experiencia han demostrado que no es un capricho, es una necesidad. Las aplicaciones empresariales tienen necesidades muy específicas de persistencia.

¿Por qué usar ORM?
Una implementación ORM es compleja, no tan compleja como la implementación de un servidor, pero más complejo que un framework de aplicaciones web como Struts o Tapestry.
¿Entonces, por qué debemos introducir otro elemento de infraestructura compleja en nuestro sistema? ¿Valdrá la pena? Según mi experiencia, una vez superada la curva de aprendizaje, si vale la pena y mucho, déjame darte unas cuantas razones.

Primero un mito, una supuesta ventaja de un ORM es que no necesitas usar sentencias SQL, es así de transparente, solo manipulas objetos. Para mi, es un mito, ya que en la realidad he tenido que usar SQL, pero muy poco. Aun así es aconsejable tener una amplia experiencia y nivel suficiente de familiaridad con el lenguaje SQL y el modelo de datos relacional, con el fin de trabajar mas facilmente con ORM. Ahora sí, vamos a ver algunos de los beneficios de la ORM e Hibernate.
Productividad
El código relacionado con la persistencia puede ser tal vez el código más tedioso en una aplicación Java, claro, usando JDB.
Hibernate elimina gran parte del trabajo pesado (más de lo que era de esperar) y le permite concentrarse en el problema de negocio.
No importa qué estrategia de desarrollo de aplicaciones prefieras usar, ya sea que primero diseñes tu modelo relacional o tu modelo de objetos, Hibernate te ayudará a reducir el tiempo de desarrollo.
Mantenibilidad
Menos líneas de código hacen que el sistema sea más comprensible, porque se enfoca en la lógica de negocio. Lo más importante, un sistema con menos código es más fácil de refactorizar. Automáticamente el mapeo objeto-relacional sustancialmente reduce las lineas de codigo.
Sin embargo, hay otras razones por las que una aplicación de Hibernate es más fácil de mantener. En los sistemas con persistencia codificado a mano, existe una tensión inevitable entre la representación relacional y el modelo de objetos de la aplicación del negocio. Los cambios en uno casi siempre implican cambios en el otro, y a menudo el diseño de una representación se ve comprometida para dar cabida a la existencia del otro. (Lo que casi siempre ocurre en la práctica es que el modelo de objetos del negocio se vea comprometida.) ORM proporciona un amortiguador entre los dos modelos, lo que permite un uso más elegante de la programación orientación a objetos en el lado de Java.
Rendimiento
La persistencia codificado a mano siempre puede ser más eficiente, y a menudo puede ser más rápido que la persistencia automatizada. Esto es cierto en el mismo sentido que es cierto que el código ensamblador siempre puede ser al menos más rápido que el código de Java, o un analizador escrito a mano siempre puede ser al menos más rápido que un analizador sintáctico generado por YACC o Antlr. Sin embargo, poner en balanza el tiempo enorme que nos toma en codificar contra el tiempo despreciable que perdemos en rendimiento del código automatizado, creo que es justificable, además, las personas que implementan el software ORM probablemente tenían mucho más tiempo para investigar optimizaciones de rendimiento de lo que nosotros tenemos. 
La independencia del proveedor
Un ORM abstrae su aplicación de la base de datos Relacional y del lenguaje SQL. Si la herramienta es compatible con un número de diferentes bases de datos (y la mayoría lo hace), esto confiere un cierto nivel de portabilidad de la aplicación. Aunque en la realidad no es llegar y cambiar de implementación así por así, se requiere un poco de trabajo para manejar las particularidades de cada implementación para no perder la potencia que ofrece cada una. Sin embargo, por lo general es mucho más fácil desarrollar una aplicación multiplataforma utilizando ORM, incluso si no requieres la capacidad multiplataforma, un ORM todavía puede ayudar a mitigar algunos de los riesgos asociados con el proveedor. Además, la independencia de base de datos ayuda en escenarios de desarrollo donde los desarrolladores utilizan una base de datos local light, pero en producción utilizan una base de datos distinta.

Hibernate es ORM bastante maduro, potente y hasta cierto punto fácil de usar, me ha sorprendido como ha evolucionado, en sus primeras versiones era muy tedioso trabajar con el, pero en las últimas el trabajo se ha simplificado muchísimo. Yo lo usé en sus primeras versiones para luego desesperarme y dejarlo en el olvido, lo retomé en el 2014 cuando ya estaba muy maduro,y así hoy lo uso en cada requerimiento de persistencia de datos.

Referencia
Christian Bauer and Gavin King. (2006). Java Persistence with Hibernate. United States of America: Manning.

Mike Keith, Jason Cranford Teague. (2013). Pro JPA 2. Estados Unidos: Apress.


2 comentarios:

  1. Roberto Lopez, amigo, inspiracion, buen hombre, gente a la que uno debe conservar, muy buen aporte.

    ResponderEliminar
  2. Y aun hay personas que te defienden SQL nativo en una aplicación

    ResponderEliminar