O DAO com Spring e Hibernate
1. Visão geral
Este artigo mostrará comoimplement the DAO with Spring and Hibernate. Para a configuração principal do Hibernate, verifique o artigoHibernate 5 with Spring anterior.
2. Não há mais modelos de primavera
Iniciando Spring 3.0 e Hibernate 3.0.1,the Spring HibernateTemplate is no longer necessary para gerenciar a Sessão do Hibernate. Agora é possível fazer uso decontextual sessions -sessions managed directly by Hibernatee ativo em todo o escopo de uma transação.
Como conseqüência, agora é a melhor prática usar a API do Hibernate diretamente em vez deHibernateTemplate.. Isso irá desacoplar totalmente a implementação da camada DAO do Spring.
2.1. Tradução de exceção sem oHibernateTemplate
A tradução de exceções era uma das responsabilidades deHibernateTemplate - traduzir as exceções de baixo nível do Hibernate para as exceções genéricas do Spring de nível superior.
Sem o modelo, anotaçãothis mechanism is still enabled and activefor all the DAOs annotated with the @Repository. Por trás disso, ele usa um pós-processador de bean Spring que aconselhará todos os beans@Repository com todos osPersistenceExceptionTranslator encontrados no contexto Spring.
Uma coisa a lembrar é que a tradução de exceção usa proxies. Para que o Spring possa criar proxies em torno das classes DAO, eles não devem ser declarados comofinal.
2.2. Gerenciamento de sessão do Hibernate sem o modelo
Quando o suporte do Hibernate para sessões contextuais foi lançado, oHibernateTemplate basicamente se tornou obsoleto. De fato, o Javadoc da classe agora destaca esse aspecto (em negrito no original):
NoteA partir do Hibernate 3.0.1, o código de acesso transacional do Hibernate também pode ser codificado no estilo Hibernate simples. Portanto, para projetos recém-iniciados, considere adotar o estilo Hibernate3 padrão de codificação de objetos de acesso a dados, baseado em \ {@ link org.hibernate.SessionFactory # getCurrentSession ()}.
3. O DAO
Começaremos comthe base DAO – an abstract, parametrized DAO, que oferece suporte às operações genéricas comuns e que podemos estender para cada entidade:
public abstract class AbstractHibernateDAO< T extends Serializable >{
private Class< T > clazz;
@Autowired
private SessionFactory sessionFactory;
public void setClazz(Class< T > clazzToSet) {
clazz = clazzToSet;
}
public T findOne(long id) {
return (T) getCurrentSession().get( clazz, id );
}
public List< T > 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();
}
}
Alguns aspectos são interessantes aqui - como discutido, o DAO abstrato não estende nenhum template Spring (comoHibernateTemplate). Em vez disso, o HibernateSessionFactory é injetado diretamente no DAO, e terá o papel da API principal do Hibernate, por meio doSession contextual que expõe:
this.sessionFactory.getCurrentSession();
Além disso, observe que o construtor recebe oClass da entidade como um parâmetro a ser usado nas operações genéricas.
Agora, vamos olhar paraan example implementation of this DAO, para uma entidadeFoo:
@Repository
public class FooDAO extends AbstractHibernateDAO< Foo > implements IFooDAO{
public FooDAO(){
setClazz(Foo.class );
}
}
4. Conclusão
Este artigo abordou a configuração e implementação da camada de persistência com o Hibernate e Spring.
Foram discutidos os motivos para deixar de confiar nos modelos para a camada DAO, bem como possíveis armadilhas da configuração do Spring para gerenciar transações e a Sessão do Hibernate. O resultado final é uma implementação leve e limpa do DAO, com quase nenhuma dependência do Spring em tempo de compilação.
A implementação deste projeto simples pode ser encontrada emthe github project.