Proseguiamo ora creando un'implementazione specifica per Hibernate del nostro BookDao
. Come per JDBC, Spring ci viene in aiuto fornendo HibernateTemplate: uno specifico template che si fa carico delle operazioni di gestione, tra le quali:
- Richiesta della connessione alla factory
- Apertura della transazione
- Gestione delle eccezioni
- Commit/Rollback della transazione
- Chiusura della connessione
Unitamente a HibernateTemplate
Spring mette a disposizione la classe di supporto HibernateDaoSupport per facilitarne l'injection all'interno dei DAO. Estendendo questa classe sarà sufficiente richiamare il metodo getHibernateTemplate()
per poter avere un hibernate template da utilizzare.
public class BookHibernateDaoSupport extends HibernateDaoSupport implements BookDao {
@Transactional
public int bookCount() {
return findAllBooks().size();
}
@Transactional
public void delete(String isbn) {
Book book = (Book) getHibernateTemplate().get(Book.class, isbn);
getHibernateTemplate().delete(book);
}
@Transactional(readOnly = true)
public List findAllBooks() {
return getHibernateTemplate().find("from Book");
}
@Transactional(readOnly = true)
public Book findByISBN(String isbn) {
return (Book) getHibernateTemplate().get(Book.class, isbn);
}
@Transactional
public void insert(Book book) {
getHibernateTemplate().saveOrUpdate(book);
}
public void update(Book book) {
getHibernateTemplate().saveOrUpdate(book);
}
}
Fino ad ora non abbiamo ancora parlato del problema di transazioni, supponendo che ogni operazione effettuata dal DAO sia di per sé univoca. Nella maggior parte dei casi invece quello che si vuole ottenere è che le operazioni effettuare dai metodi del DAO siano transazionali, cioè abbiano un senso compiuto nella loro interezza.
Questo comportamento è reso possibile dall'utilizzo dell'apposita annotation @Trasactional
con la quale è possibile richiedere al framework che tutte le chiamate ai metodi coinvolti siano trattati nella stessa transazione.