La compatibilidad con objetos de acceso a datos/DAO en Spring tiene como objetivo facilitar el trabajo con tecnologías de acceso a datos (como JDBC, Hibernate o JPA). Esto le permite cambiar fácilmente entre las tecnologías de almacenamiento persistente mencionadas anteriormente sin tener que preocuparse por detectar excepciones específicas de cada tecnología.

Jerarquía consistente de excepciones

Spring proporciona una transición conveniente desde excepciones específicas de tecnología como SQLException a su propia jerarquía de clases de excepción, en la que la excepción raíz es DataAccessException. Estas excepciones envuelven la excepción original, por lo que no hay riesgo de que pierda información sobre lo que pudo haber salido mal.

Además de las excepciones JDBC, Spring también puede incluir excepciones específicas de JPA e Hibernate, transformándolas en un conjunto de excepciones de tiempo de ejecución organizadas. Esto le permite manejar la mayoría de las excepciones persistentes no recuperables solo en los niveles apropiados, sin recurrir a molestos bloques repetitivos de captura y lanzamiento y declaraciones de excepción en sus DAO. (Sin embargo, aún puede detectar y manejar excepciones cuando sea necesario). Como se mencionó anteriormente, 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.

La explicación anterior también se aplica a las diferentes clases de plantilla en el soporte de Spring para diferentes marcos ORM. Si utiliza clases basadas en interceptores, la aplicación debe manejar el manejo de HibernateExceptions y PersistenceExceptions en sí, preferiblemente delegándolo al convertHibernateAccessException(..) o convertJpaAccessException(..) de la utilidad SessionFactoryUtils, respectivamente. Estos métodos convierten excepciones en excepciones que son compatibles con las excepciones en la jerarquía de excepciones org.springframework.dao. Dado que las PersistenceExceptions no están marcadas, también se pueden generar (a expensas de la abstracción escrita del DAO en términos de excepciones).

La siguiente imagen muestra la jerarquía de excepciones que ofrece Spring. (Tenga en cuenta que la jerarquía de clases que se muestra en la figura muestra solo una parte de toda la jerarquía DataAccessException.

Anotaciones utilizadas para configurar DAO o clases de repositorio

La mejor manera de garantizar que sus objetos de acceso a datos (DAO) o repositorios resuelvan excepciones es utilizar la anotación @Repository. Esta anotación también permite que las herramientas de soporte de escaneo de componentes encuentren y configuren sus DAO y repositorios sin tener que proporcionarles registros de configuración XML. El siguiente ejemplo muestra cómo utilizar la anotación @Repository:

Java
@Repository 
public class SomeMovieFinder implements MovieFinder {
    // ...
}
  1. Anotación @Repository.
Kotlin
@Repository 
class SomeMovieFinder : MovieFinder {
    // ...
}
  1. Anotación @Repository.

Cualquier implementación o repositorio de DAO requiere acceso a un recurso de almacenamiento persistente, dependiendo de la tecnología de almacenamiento persistente utilizada. Por ejemplo, un repositorio basado en JDBC necesita acceso a DataSource desde JDBC, mientras que un repositorio basado en JPA necesita acceso a EntityManager. La forma más sencilla de lograr esto es inyectar una dependencia de recursos usando uno de los @Autowired, @Inject, @Resource o @PersistenceContext anotaciones. El siguiente ejemplo funciona en relación con el repositorio JPA:

Java
@Repository
public class JpaMovieFinder implements MovieFinder {
    @PersistenceContext
    private EntityManager entityManager;
    // ...
}
Kotlin
@Repository
class JpaMovieFinder : MovieFinder {
    @PersistenceContext
    private lateinit var entityManager: EntityManager
    // ...
}

Si está utilizando las API clásicas de Hibernate, puede implementar un SessionFactory, como se muestra en el siguiente ejemplo:

Java
@Repository
public class HibernateMovieFinder implements MovieFinder {
    private SessionFactory sessionFactory;
    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
    // ...
}
Kotlin
@Repository
class HibernateMovieFinder(private val sessionFactory: SessionFactory) : MovieFinder {
    // ...
}

El último ejemplo que demostraremos es de una herramienta de soporte JDBC típica. DataSource se puede inyectar en un método de inicialización o constructor donde se crea JdbcTemplate y otras clases de soporte de acceso a datos (como SimpleJdbcCall, etc.) usando este fuente deDataSource. El siguiente ejemplo descubre y vincula automáticamente DataSource:

Java
@Repository
public class JdbcMovieFinder implements MovieFinder {
    private JdbcTemplate jdbcTemplate;
    @Autowired
    public void init(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }
    // ...
}
Kotlin
@Repository
class JdbcMovieFinder(dataSource: DataSource) : MovieFinder {
    private val jdbcTemplate = JdbcTemplate(dataSource)
    // ...
}
Para obtener detalles sobre cómo configurar el contexto de su aplicación para aprovechar estas anotaciones, consulte la descripción específica de cada tecnología de almacenamiento persistente.