Let's create the following DAO implanting class:
package com.packt.patterninspring.chapter8.bankapp.dao; import org.hibernate.SessionFactory; import org.springframework.stereotype.Repository; import org.springframework.beans.factory.annotation.Autowired; @Repository public class AccountDaoImpl implements AccountDao { @Autowired private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Override public Integer totalAccountsByBranch(String branchName) { String sql = "SELECT count(*) FROM Account WHERE branchName =
"+branchName; return this.sessionFactory.getCurrentSession().createQuery(sql,
Integer.class).getSingleResult(); } @Override public Account findOne(long accountId) { return (Account)
this.sessionFactory.currentSession().
get(Account.class, accountId); } @Override public Account findByName(String name) { return (Account) this.sessionFactory.currentSession().
createCriteria(Account.class) .add(Restrictions.eq("name", name)) .list().get(0); } @Override public List<Account> findAllAccountInBranch(String branchName) { return (List<Account>) this.sessionFactory.currentSession()
.createCriteria(Account.class).add(Restrictions.eq("branchName",
branchName)).list(); } }
As you can see in the preceding code, AccountDaoImpl is a DAO implementation class, which is injected with Hibernate's SessionFactory bean by using the @Autowired annotation. The DAO implementations described earlier will throw unchecked Hibernate PersistenceExceptions--it is not desirable to let these propagate up to the service layer or other users of the DAOs. But the Spring AOP module allows translation to Spring's rich, vendor-neutral DataAccessException hierarchy--it hides the access technology used. Spring provides this capability out of the box by annotating the DAO implementation class with @Repository, and you just need to define a Spring-provided BeanPostProcessor, that is, PersistenceExceptionTranslationPostProcessor.
Let's add an exception translation to our Hibernate DAO implementation class; we can do this by just adding a PersistenceExceptionTranslationPostProcessor bean to the Spring application context, as follows:
@Bean public BeanPostProcessor persistenceTranslation() { return new PersistenceExceptionTranslationPostProcessor(); }
The preceding registered bean PersistenceExceptionTranslationPostProcessor is responsible for adding an adviser for the beans which are annotated with the @Repository annotation, and it is re-thrown as a Spring-specific unchecked data access exception for any platform-specific exceptions caught in the code.
Let's see, in the next section, how Spring manages transactions across the business and persistence layers of the Spring application.