¿Qué es Hibernate? Fundamentos de la implementación de Hibernate Core

Publicado: 2013-04-17

Ejemplo de hibernación de Java

Hibernate es un proyecto de marco de persistencia Java de código abierto. Realice un potente mapeo relacional de objetos y consulte bases de datos utilizando HQL y SQL.

En general, las bibliotecas ampliamente utilizadas están bien diseñadas e implementadas, y es muy interesante aprender de ellas algunas de las mejores prácticas de codificación.

Echemos un vistazo dentro de la biblioteca central de hibernate y descubramos algunas de sus claves de diseño.

En este post Hibernate Core es analizado por JArchitect para profundizar en su diseño e implementación.

Paquete por característica

Package-by-feature utiliza paquetes para reflejar el conjunto de características. Coloca todos los elementos relacionados con una sola función (y solo esa función) en un solo directorio/paquete. Esto da como resultado paquetes con alta cohesión y alta modularidad, y con un acoplamiento mínimo entre paquetes. Los elementos que funcionan en estrecha colaboración se colocan uno al lado del otro.

El núcleo de Hibernate contiene muchos paquetes, cada uno está relacionado con una función específica hql, sql y otras.

Paquetes básicos de Hibernate - Crunchify.com

Acoplamiento

Es deseable un acoplamiento bajo porque un cambio en un área de una aplicación requerirá menos cambios en toda la aplicación. A la larga, esto podría aliviar una gran cantidad de tiempo, esfuerzo y costo asociados con la modificación y la adición de nuevas funciones a una aplicación.

Aquí hay tres beneficios clave derivados del uso de interfaces:

  • Una interfaz proporciona una manera de definir un contrato que promueve la reutilización. Si un objeto implementa una interfaz, entonces ese objeto debe cumplir con un estándar. Un objeto que usa otro objeto se llama consumidor. Una interfaz es un contrato entre un objeto y su consumidor.
  • Una interfaz también proporciona un nivel de abstracción que facilita la comprensión de los programas. Las interfaces permiten a los desarrolladores comenzar a hablar sobre la forma general en que se comporta el código sin tener que entrar en muchos detalles específicos.
  • Una interfaz impone un acoplamiento bajo entre los componentes, lo que facilita la protección del consumidor de la interfaz de cualquier cambio de implementación en las clases que implementan las interfaces.

Busquemos todas las interfaces definidas por Hibernate Core, para eso usamos CQLinq para consultar el código base.

jboss11- Crunchify.com

Si nuestro objetivo principal es hacer cumplir un acoplamiento bajo, hay un error común al usar interfaces que podría matar la utilidad de usarlas. Es el uso de clases concretas en lugar de interfaces, y para explicar mejor este problema tomemos el siguiente ejemplo:

La clase A implementa la interfaz IA que contiene el método de cálculo (), la clase de consumidor C se implementa así

La Clase C en lugar de hacer referencia a la interfaz IA, hace referencia a la clase A, en este caso perdemos el beneficio de bajo acoplamiento, y esta implementación tiene dos inconvenientes principales:

  • Si decidimos usar otra implementación de IA, debemos cambiar el código de la clase C.
  • Si se agregan algunos métodos a A que no existen en IA, y C los usa, también perdemos el beneficio del contrato de usar interfaces.

C# introdujo la capacidad de implementación de interfaz explícita en el lenguaje para garantizar que nunca se llamará a un método del IA desde una referencia a clases concretas, sino solo desde una referencia a la interfaz. Esta técnica es muy útil para evitar que los desarrolladores pierdan el beneficio de usar interfaces.

Con JArchitect podemos comprobar este tipo de errores usando CQLinq , la idea es buscar todos los métodos de clases concretas utilizadas directamente por otros métodos.

hibernate2 Detalles - Crunchify.com

Por ejemplo, el método getEntityPersister de SessionFactoryImpl que implementa la interfaz SessionFactoryImplementor está relacionado con este problema.

Busquemos métodos invocando directamente SessionFactoryImpl.getEntityPersister.

Tutorial de hibernación - Crunchify.com

Métodos como SessionImpl.instantiate invocan directamente a getEntityPersister, en lugar de pasar por interfaz, lo que rompe el beneficio de usar interfaces. Afortunadamente, hibernate core no contiene muchos métodos que tengan este problema.

Acoplamiento con vasos externos

Cuando se utilizan librerías externas, es mejor comprobar si podemos cambiar fácilmente una librería de terceros por otra sin afectar a toda la aplicación, hay muchas razones que nos pueden animar a cambiar una librería de terceros.

La otra biblioteca podría:

  • Tener más características
  • Mas poderoso
  • Más seguro

Tomemos el ejemplo de antlr lib que solía analizar las consultas hql, e imaginemos que se creó otro analizador más poderoso que antlr, ¿podríamos cambiar el antlr por el nuevo analizador fácilmente?

Para responder a esta pregunta, busquemos qué métodos de hibernación lo usan directamente:

Detalles de Hibernate - Crunchify

Y cuáles lo usaron indirectamente:

Hibernate Funda - Tutoriales de Java - Crunchify

Muchos métodos usan antlr directamente, lo que hace que hibernate core esté muy acoplado con él, y cambiar antlr por otro no es una tarea fácil. este hecho no significa que tengamos un problema en el diseño de hibernación, pero debemos tener cuidado al usar una biblioteca de terceros y verificar si una biblioteca de terceros debe estar acoplada baja o no con la aplicación.

Cohesión

El principio de responsabilidad única establece que una clase debe tener una, y solo una, razón para cambiar. Se dice que tal clase es cohesiva. Un valor alto de LCOM generalmente señala una clase poco cohesiva. Hay varias métricas LCOM. El LCOM toma sus valores en el rango [0-1]. El LCOMHS (HS significa Henderson-Sellers) toma sus valores en el rango [0-2]. Tenga en cuenta que la métrica LCOMHS a menudo se considera más eficiente para detectar tipos no cohesivos.

Un valor de LCOMHS superior a 1 debe considerarse alarmante.

En general las clases más preocupadas por la cohesión son las clases que tienen muchos métodos y campos.

Busquemos tipos que tengan muchos métodos y campos.

hibernate6 - Crunchificar

Solo unos pocos tipos se ven afectados por esta consulta, y para todos ellos el LCOMHS es menor que 1.

Uso de anotaciones

El desarrollo basado en anotaciones libera a los desarrolladores de Java del dolor de una configuración engorrosa. Y danos una característica poderosa para liberar el código fuente del código repetitivo. También es menos probable que el código resultante contenga errores.

Busquemos todas las anotaciones definidas por hibernate core.

hibernate7 - Crunchify.com

Se definen muchas anotaciones, lo que hace que Hibernate sea fácil de usar para los desarrolladores y se evita el dolor de cabeza de los archivos de configuración.

Conclusión

Hibernate Core es un buen ejemplo de proyectos de código abierto para aprender, no dudes en echarle un vistazo.