2012-01-04 10 views
5

che sto attualmente lavorando con integration framework MyBatis-Spring e questo è quello che ho letto da docs:Il mappatore MyBatis è stato iniettato direttamente nella classe di servizio. Che dire delle eccezioni?

Invece di oggetti di accesso ai dati di codice (DAO) utilizzando manualmente SqlSessionDaoSupport o SqlSessionTemplate, Mybatis-Spring offre invece una fabbrica di delega : MapperFactoryBean. Questa classe consente di iniettare le interfacce di mapping dei dati direttamente nei bean di servizio. Quando usi i mapper, li chiami semplicemente come hai sempre chiamato i tuoi DAO , ma non dovrai codificare alcuna implementazione DAO perché MyBatis-Spring creerà un proxy per tu.

Questa è una funzionalità molto interessante ... ma per quanto riguarda la gestione delle eccezioni? Dove dovrei tradurre gli errori SQL? Nel mio livello di servizio? Ma non violerebbe i modelli DAO del servizio?

Esempio:

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); 
    } 

E 'OK per tradurre eccezioni a livello di servizio?

Come dovrebbe essere fatto?

Grazie in anticipo per il vostro consiglio.

risposta

6

Avendo usato di recente mybatis-spring per un progetto, mi sono imbattuto nello stesso ostacolo. Inoltre non volevo sprecare la mia classe di servizio con la gestione delle eccezioni DAO, soprattutto perché alcuni metodi nel mio livello di servizio richiedevano l'accesso in sola lettura a molte tabelle diverse.

La soluzione a cui sono arrivato è stata quella di rilevare le eccezioni nel livello di servizio, ma creare il proprio tipo di eccezione che accetta l'eccezione rilevata come parametro. Questo può quindi filtrare quale tipo di messaggio di errore deve essere contenuto quando l'eccezione è effettivamente costruita e rimuovere la necessità di trovare la corrispondenza delle stringhe (almeno nel livello di servizio).

Sei vicino a quello lì, tranne il AccountServiceException avrebbe un costruttore che ha preso il Exception e come parametro. Ho anche scelto di provare a fare tutto il mio accesso ai dati il ​​prima possibile e di avvolgerlo tutto in un solo tentativo/cattura. Poiché lo MapperFactoryBean traduce sempre le eccezioni generate in Spring DataAccessExceptions, non devi preoccuparti di rilevare altri tipi di eccezioni quando esegui l'accesso ai dati.

Esito a considerare questa risposta come una cosa del genere - più di una condivisione dell'esperienza che ho riscontrato e ho anche esitato.

+0

Risposta molto bella! Grazie! –

1

La conversione di DataAccessException di livello basso lanciati da MyBatis a quelli definiti dall'applicazione nel livello di servizio è una pratica standard.

Di solito è connesso alla gestione delle transazioni poiché non è possibile gestire la transazione che copre più DAO nel livello DA.

Quindi sì va bene e anche consigliato.

Di solito registro le eccezioni generate da DAO nel log degli errori e restituisco qualcosa definito dall'applicazione.

Problemi correlati