2012-01-04 9 views
5

trabajo actualmente con marco de integración MyBatis-Spring y eso es lo que he leído de documentos:MyBatis mapper inyectado directamente en la clase de servicio. ¿Qué hay de las excepciones?

En lugar de objetos de acceso a datos de código (DAO) de forma manual utilizando SqlSessionDaoSupport o SqlSessionTemplate, mybatis-resorte proporciona una fábrica de proxy : MapperFactoryBean. Esta clase le permite inyectar interfaces de mapeador de datos directamente en sus beans de servicio. Cuando utilice mappers, simplemente llámelos como siempre ha llamado a sus DAO , pero no necesitará codificar ninguna implementación DAO porque MyBatis-Spring creará un proxy para usted.

Esa es una característica muy buena ... pero ¿qué pasa con el manejo de excepciones? ¿Dónde debería traducir los errores de SQL? En mi capa de servicio? Pero, ¿no violaría los patrones DAO de servicio?

Ejemplo:

public final class AccountServiceImpl implements AccountService { 
(...) 
    private AccountMapper accountMapper; 
(...) 
    @Override 
    public void addAccount(Account account) throws AccountServiceException { 

     //Validating, processing, setting timestamps etc. 
     (...) 

     //Persistence: 
     int rowsAffected; 
     try { 
      rowsAffected = accountMapper.insertAccount(account); 
     } catch (Exception e) { 
      String msg = e.getMessage(); 
      if (msg.contains("accounts_pkey")) 
       throw new AccountServiceException("Username already exists!"); 
      if (msg.contains("accounts_email_key")) 
       throw new AccountServiceException("E-mail already exists!"); 
      throw new AccountServiceException(APP_ERROR); 
     } 

     LOG.debug("Rows affected: '{}'", rowsAffected); 

     if (rowsAffected != 1) 
      throw new AccountServiceException(APP_ERROR); 
    } 

¿Está bien para traducir excepciones en la capa de servicio?

¿Cómo se debe hacer?

Gracias de antemano por su asesoramiento.

Respuesta

6

Habiendo utilizado recientemente mybatis-spring para un proyecto, encontré el mismo obstáculo. Tampoco quería ensuciar mi clase de servicio con el manejo de excepciones de DAO, particularmente porque algunos métodos en mi capa de servicio requerían acceso de solo lectura a muchas tablas diferentes.

La solución a la que llegué fue capturar las excepciones en la capa de servicio pero crear su propio tipo de excepción que toma la excepción atrapada como parámetro. Esto puede filtrar el tipo de mensaje de error que se debe contener cuando la excepción se construye realmente y eliminar la necesidad de coincidencia de cadenas (en la capa de servicio al menos).

Estás cerca de eso, excepto que el AccountServiceException tendría un constructor que tomara el Exception e como parámetro. También decidí intentar y hacer todo mi acceso a los datos lo antes posible y envolverlo todo en una sola prueba/captura. Como el MapperFactoryBean siempre traduce excepciones lanzadas al Spring DataAccessExceptions, no tiene que preocuparse por detectar otros tipos de excepciones al acceder a los datos.

Dudo en considerar esta una respuesta como tal, más de un intercambio de experiencias, dado que me encontré con eso y también lo dudé.

+0

Muy buena respuesta! ¡Gracias! –

1

Traducir nivel bajo DataAccessExceptions lanzado por MyBatis a los definidos por la aplicación en la capa de servicio es una práctica estándar.

Por lo general, está conectado al manejo de transacciones ya que no puede manejar la transacción que abarca varios DAO en la capa DA.

Así que sí, está bien y hasta se recomienda.

Normalmente registro las excepciones lanzadas por DAO en el registro de errores y vuelvo a lanzar algo definido por la aplicación.

Cuestiones relacionadas