Spring Framework admite la integración con Java Persistence API (JPA) y admite Hibernate nativo para recursos gestión, implementación de objetos de acceso a datos (DAO) y estrategia de transacciones. Por ejemplo, Hibernate tiene soporte de primera clase con varias funciones útiles de IoC que resuelven muchos problemas comunes de integración de Hibernate. Puede configurar todas las funciones admitidas para las herramientas de mapeo OR (Object Relational) mediante la inyección de dependencia. Pueden participar en la gestión de transacciones y recursos de Spring, y corresponden a las jerarquías de excepciones y transacciones DAO escritas de Spring. El estilo de integración recomendado es codificar DAO en lugar de simples API de Hibernate o JPA.

Spring aporta importantes mejoras de funcionalidad a la capa ORM elegida al crear aplicaciones de acceso a datos. Puede utilizar tantas herramientas de soporte de integración como desee y luego comparar esos esfuerzos de integración con el costo y el riesgo de construir una infraestructura similar internamente. Puede utilizar la mayor parte del soporte ORM al igual que las bibliotecas, independientemente de la tecnología, porque todo está diseñado como un conjunto de JavaBeans reutilizables. El ORM en el contenedor Spring IoC facilita su configuración e implementación. Por lo tanto, la mayoría de los ejemplos en esta sección muestran la configuración dentro de un contenedor Spring.

Las ventajas de usar Spring Framework para crear ORM DAO son:

  • Pruebas simplificadasEl enfoque IoC de Spring facilita el intercambio de implementaciones y configuraciones de instancias SessionFactory de Hibernate, instancias DataSource de JDBC, administradores de transacciones y mapeados implementaciones de objetos (si es necesario). Esto, a su vez, hace que sea mucho más fácil probar cada fragmento de código persistente por separado.

  • Excepciones generales de acceso a datos. Spring puede encapsular excepciones de su Herramienta ORM, transformándolas de excepciones nativas (potencialmente comprobadas) a una jerarquía DataAccessException común. Esta característica le permite manejar la mayoría de las excepciones persistentes no recuperables solo en los niveles apropiados, sin los molestos clichés de capturar, lanzar y declarar excepciones. Pero aún puedes detectar y manejar excepciones según sea necesario. Recuerde que las excepciones JDBC (incluidos los dialectos específicos de la base de datos) también se traducen a la misma jerarquía, lo que significa que puede realizar algunas operaciones JDBC dentro del modelo de programación consistente.

  • Gestión de recursos compartidos Los contextos de aplicaciones Spring pueden manejar la ubicación y configuración de instancias SessionFactory de Hibernate, instancias EntityManagerFactory de JPA, DataSource código de instancias> de JDBC y otros recursos relacionados. Esto facilita la gestión y el cambio de estos valores. Spring ofrece un manejo eficiente, simple y seguro de recursos de almacenamiento persistentes. Por ejemplo, el código dependiente que usa Hibernate normalmente necesita usar la misma Session de Hibernate para garantizar la eficiencia y el procesamiento adecuado de las transacciones. Spring facilita la creación y vinculación de una Session al hilo actual de forma transparente al exponer la Session actual a través de una SessionFactory de Hibernate. Por lo tanto, Spring resuelve muchos de los problemas crónicos del uso típico de Hibernate para cualquier entorno JTA local o transaccional.

  • Gestión de transacciones integrada. Puede envolver ORM codifique un interceptor de método declarativo basado en programación orientada a aspectos (AOP), ya sea utilizando la anotación @Transactional o configurando explícitamente AOP-Advice para transacciones en un archivo de configuración XML. En ambos casos, la semántica de las transacciones y el manejo de excepciones (reversión, etc.) se realizan por usted. Como se describe en la sección "Gestión de recursos y transacciones" , también puede cambiar varios administradores de transacciones sin afectar el código relacionado con ORM. Por ejemplo, puede alternar entre transacciones locales y JTA, con los mismos servicios enriquecidos (como transacciones declarativas) disponibles en ambos escenarios. Además, el código asociado con JDBC se puede integrar completamente transaccionalmente con el código utilizado para ORM. Esto es útil para el acceso a datos que no es adecuado para ORM (como el procesamiento por lotes y la transmisión BLOB), pero que aún necesita compartir transacciones comunes con operaciones ORM.

Para obtener un soporte ORM más completo, incluido el soporte para tecnologías de bases de datos alternativas como MongoDB, vale la pena echar un vistazo a la colección de proyectos Datos de primavera. Si es usuario de JPA, "Comenzando con el acceso a datos con JPA" de https://spring.io sería una excelente introducción.

Enfoques generales para la integración ORM

Esta sección analiza recomendaciones que se aplican a todas las tecnologías ORM. La sección sobre Hibernate proporciona más detalles y también demuestra estas características y configuraciones en contexto.

El objetivo principal de la integración ORM en Spring es una composición clara de la aplicación (en cualquier tecnología de transacción y acceso a datos) y vinculación libre de los objetos de la aplicación: no más dependencias de servicios comerciales en el acceso a datos o la estrategia de transacción, ni recursos de búsqueda codificados, ni objetos individuales difíciles de reemplazar y sin registros de servicios personalizados. El objetivo es proporcionar un enfoque simple y coherente para descubrir y vincular objetos de aplicaciones y al mismo tiempo hacerlos lo más reutilizables posible y libres de dependencias de contenedores. Todas las funciones de acceso a datos individuales se pueden usar por separado, pero también funcionan muy bien con el concepto de contexto de aplicación de Spring, proporcionando configuración basada en XML y referencias cruzadas con instancias regulares de JavaBean que no necesariamente necesitan ser compatibles con Spring. En una aplicación Spring típica, muchos objetos importantes son JavaBeans: patrones de acceso a datos, objetos de acceso a datos, administradores de transacciones, servicios comerciales que utilizan objetos de acceso a datos y administradores de transacciones, solucionadores de vistas web, controladores web que utilizan servicios comerciales, etc.

Gestión de recursos y transacciones

Las aplicaciones empresariales típicas tienen mucho código repetitivo para gestionar los recursos. Muchos proyectos intentan encontrar sus propias soluciones, a veces sacrificando la resolución de problemas adecuada en aras de la conveniencia de la programación. Spring aboga por soluciones simples para el manejo adecuado de recursos, concretamente IoC a través de plantillas en el caso de JDBC y el uso de interceptores AOP para tecnologías ORM.

El marco garantiza un manejo adecuado de recursos y una traducción apropiada de excepciones específicas de API a Excepciones de infraestructura de jerarquía no controladas. Spring introduce una jerarquía de excepciones DAO aplicable a cualquier estrategia de acceso a datos. En el caso de JDBC directo, la clase JdbcTemplate mencionada en la sección anterior maneja conexiones y traducción adecuada de SQLException a la jerarquía DataAccessException, incluida la traducción de códigos de error SQL específicos de la base de datos en clases de excepción significativas. Para tecnologías ORM, consulte la siguiente sección sobre cómo aprovechar los mismos beneficios de la conversión de excepciones.

Cuando se trata de gestión de transacciones, la clase JdbcTemplate se conecta al soporte de transacciones de Spring y admite transacciones JTA y JDBC a través de sus respectivos administradores de transacciones Spring. En términos de tecnologías ORM compatibles, Spring ofrece soporte para Hibernate y JPA a través de los administradores de transacciones de Hibernate y JPA, así como soporte para JTA. Para obtener más información sobre el soporte de transacciones, consulte el capítulo "Gestión de transacciones".

Conversión de excepciones

Si se utilizan Hibernate o JPA en una DAO, entonces debe decidir cómo manejar las clases de excepción nativas de la tecnología de almacenamiento persistente. DAO genera una subclase de HibernateException o PersistenceException dependiendo de la tecnología. Todas estas excepciones son excepciones en tiempo de ejecución y no deben declararse ni detectarse. Es posible que también tengas que lidiar con IllegalArgumentException y IllegalStateException. Esto significa que las personas que llaman solo pueden manejar excepciones que se consideran críticas si quieren evitar depender de la propia estructura de excepciones de la tecnología de persistencia. Es imposible determinar causas específicas (como una falla de bloqueo optimista) sin vincular el programa de llamada con la estrategia de implementación. Esta compensación puede ser aceptable para aplicaciones que se basan en gran medida en ORM o que no necesitan un manejo especial de excepciones (o ambas). Sin embargo, Spring permite que la traducción de excepciones se aplique de forma transparente a través de la anotación @Repository. Los siguientes ejemplos (uno para la configuración de Java y otro para la configuración de XML) muestran cómo hacer esto:

Java
@Repository
public class ProductDaoImpl implements ProductDao {
    // clase cuerpo aquí... }
Kotlin
@Repository
public class ProductDaoImpl implements ProductDao {
    // cuerpo de la clase aquí... }
<beans>
    <!-- Excepción del posprocesador de conversión de beans... -->
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
    <bean id="myProductDao" class="product.ProductDaoImpl"/>
</beans>

El posprocesador busca automáticamente todos los transformadores de excepción (implementaciones de la interfaz PersistenceExceptionTranslator) y suministra todos los beans con Advice marcados con la anotación @Repository para que los solucionadores detectados puedan detectar y aplicar la conversión apropiada a las excepciones lanzadas.

En general, es posible implementar un DAO basado en la API y anotaciones de la tecnología de soporte de almacenamiento persistente convencional, mientras se aprovechan las transacciones administradas por Spring, la inyección de dependencia y la traducción transparente de excepciones (si se desea) en jerarquías de excepciones de Spring personalizadas.