Il DAO con Spring e Hibernate

1. Panoramica

Questo articolo mostrerà come implementare DAO con Spring e Hibernate . Per la configurazione di base di Hibernate, controlla il precedente articolo Hibernate 5 con Spring.

2. Niente più modelli primaverili

A partire da Spring 3.0 e Hibernate 3.0.1, Spring HibernateTemplate non è più necessario per gestire la sessione Hibernate. È ora possibile fare uso di sessioni contestuali - sessioni gestite direttamente da Hibernate e attive per tutto l'ambito di una transazione.

Di conseguenza, è ora consigliabile utilizzare direttamente l'API Hibernate invece di HibernateTemplate. Ciò disaccoppierà efficacemente l'implementazione del livello DAO da Spring completamente.

2.1. Traduzione di eccezione senza HibernateTemplate

La traduzione delle eccezioni era una delle responsabilità di HibernateTemplate : tradurre le eccezioni di Hibernate di basso livello in eccezioni di primavera generiche di livello superiore.

Senza il modello, questo meccanismo è ancora abilitato e attivo per tutti i DAO annotati con l' annotazione @Repository . Sotto il cofano, questo utilizza un postprocessore di bean Spring che consiglierà tutti i bean @Repository con tutto il PersistenceExceptionTranslator trovato nel contesto Spring.

Una cosa da ricordare è che la traduzione delle eccezioni utilizza i proxy. Affinché Spring possa creare proxy attorno alle classi DAO, questi non devono essere dichiarati come definitivi .

2.2. Gestione delle sessioni di ibernazione senza il modello

Quando è uscito il supporto di Hibernate per le sessioni contestuali, HibernateTemplate è diventato essenzialmente obsoleto. Infatti, il Javadoc della classe ora evidenzia questo aspetto (in grassetto dall'originale):

NOTA: a partire da Hibernate 3.0.1, il codice di accesso transazionale Hibernate può anche essere codificato in semplice stile Hibernate. Pertanto, per i progetti appena avviati, valuta la possibilità di adottare lo stile standard Hibernate3 di codifica degli oggetti di accesso ai dati, basato su {@link org.hibernate.SessionFactory # getCurrentSession ()}.

3. Il DAO

Inizieremo con il DAO di base, un DAO astratto e parametrizzato che supporta le operazioni generiche comuni e che possiamo estendere per ogni entità:

public abstract class AbstractHibernateDAO{ private Class clazz; @Autowired private SessionFactory sessionFactory; public void setClazz(Class clazzToSet) { clazz = clazzToSet; } public T findOne(long id) { return (T) getCurrentSession().get( clazz, id ); } public List findAll() { return getCurrentSession() .createQuery( "from " + clazz.getName() ).list(); } public void save(T entity) { getCurrentSession().persist( entity ); } public T update(T entity) { return (T) getCurrentSession().merge( entity ); } public void delete(T entity) { getCurrentSession().delete( entity ); } public void deleteById(long id) { final T entity = findOne( id); delete( entity ); } protected final Session getCurrentSession(){ return sessionFactory.getCurrentSession(); } }

Alcuni aspetti sono interessanti qui: come discusso, il DAO astratto non estende alcun modello Spring (come HibernateTemplate ). Invece, la Hibernate SessionFactory viene iniettata direttamente nel DAO, e avrà il ruolo di principale API di Hibernate, attraverso la Session contestuale che espone:

this.sessionFactory.getCurrentSession ();

Inoltre, si noti che il costruttore riceve la Classe dell'entità come parametro da utilizzare nelle operazioni generiche.

Ora, diamo un'occhiata a un'implementazione di esempio di questo DAO , per un'entità Foo :

@Repository public class FooDAO extends AbstractHibernateDAO implements IFooDAO{ public FooDAO(){ setClazz(Foo.class ); } }

4. Conclusione

Questo articolo ha trattato la configurazione e l'implementazione del livello di persistenza con Hibernate e Spring.

Sono stati discussi i motivi per smettere di fare affidamento sui modelli per il livello DAO, così come le possibili insidie ​​della configurazione di Spring per gestire le transazioni e la sessione di ibernazione. Il risultato finale è un'implementazione DAO leggera e pulita, con quasi nessuna dipendenza in fase di compilazione da Spring.

L'implementazione di questo semplice progetto può essere trovata nel progetto github.