The DAO with Spring and Hibernate – 使用Spring和Hibernate的DAO

最后修改: 2011年 12月 2日


1. Overview


This article will show how to implement the DAO with Spring and Hibernate. For the core Hibernate configuration, check out the previous Hibernate 5 with Spring article.

本文将介绍如何使用 Spring 和 Hibernate 实现 DAO。有关 Hibernate 的核心配置,请查看之前的 Hibernate 5 with Spring 文章。

2. No More Spring Templates


Starting Spring 3.0 and Hibernate 3.0.1, the Spring HibernateTemplate is no longer necessary to manage the Hibernate Session. It’s now possible to make use of contextual sessionssessions managed directly by Hibernate and active throughout the scope of a transaction.

从Spring 3.0和Hibernate 3.0.1开始,Spring HibernateTemplate不再需要来管理Hibernate Session。现在可以利用contextual sessions由 Hibernate 直接管理的会话,并在整个事务范围内处于活动状态。

As a consequence, it’s now best practice to use the Hibernate API directly instead of the HibernateTemplate. This will effectively decouple the DAO layer implementation from Spring entirely.

因此,现在最好的做法是直接使用Hibernate API而不是HibernateTemplate。这将有效地将DAO层的实现与Spring完全分离。

2.1. Exception Translation Without the HibernateTemplate


Exception Translation was one of the responsibilities of HibernateTemplate – translating the low-level Hibernate exceptions to higher level, generic Spring exceptions.


Without the template, this mechanism is still enabled and active for all the DAOs annotated with the @Repository annotation. Under the hood, this uses a Spring bean postprocessor that will advise all @Repository beans with all the PersistenceExceptionTranslator found in the Spring context.

在没有模板的情况下,这种机制仍然是有效的 对于所有用@Repository注解的DAO。在引擎盖下,这使用了一个 Spring Bean 后处理器,它将用在 Spring 上下文中发现的所有 @Repository Bean 的 PersistenceExceptionTranslator 给予建议。

One thing to remember is that exception translation uses proxies. For Spring to be able to create proxies around the DAO classes, these must not be declared as final.


2.2. Hibernate Session Management Without the Template


When Hibernate support for contextual sessions came out, the HibernateTemplate essentially became obsolete. In fact, the Javadoc of the class now highlights this aspect (bold from the original):


NOTE: As of Hibernate 3.0.1, transactional Hibernate access code can also be coded in plain Hibernate style. Hence, for newly started projects, consider adopting the standard Hibernate3 style of coding data access objects instead, based on {@link org.hibernate.SessionFactory#getCurrentSession()}.

注意:从Hibernate 3.0.1开始,事务性的Hibernate访问代码也可以用普通的Hibernate风格进行编码。因此,对于新开始的项目,考虑采用标准的Hibernate3风格来编码数据访问对象,而不是基于{@link org.hibernate.SessionFactory#getCurrentSession()}。

3. The DAO


We’ll start with the base DAO – an abstract, parametrized DAO which supports the common generic operations and that we can extend for each entity:


public abstract class AbstractHibernateDao<T extends Serializable> {
    private Class<T> clazz;

    protected SessionFactory sessionFactory;

    public final void setClazz(final Class<T> clazzToSet) {
        clazz = Preconditions.checkNotNull(clazzToSet);

    // API
    public T findOne(final long id) {
        return (T) getCurrentSession().get(clazz, id);

    public List<T> findAll() {
        return getCurrentSession().createQuery("from " + clazz.getName()).list();

    public T create(final T entity) {
        return entity;

    public T update(final T entity) {
        return (T) getCurrentSession().merge(entity);

    public void delete(final T entity) {

    public void deleteById(final long entityId) {
        final T entity = findOne(entityId);
        Preconditions.checkState(entity != null);

    protected Session getCurrentSession() {
        return sessionFactory.getCurrentSession();

A few aspects are interesting here – as discussed, the abstract DAO doesn’t extend any Spring template (such as HibernateTemplate). Instead, the Hibernate SessionFactory is injected directly in the DAO, and will have the role of the main Hibernate API, through the contextual Session it exposes:

这里有几个方面很有意思–正如所讨论的,抽象的DAO并没有扩展任何Spring模板(如HibernateTemplate)。相反,HibernateSessionFactory被直接注入DAO中,并将通过其暴露的上下文Session发挥主要Hibernate API的作用。



Also, note that the constructor receives the Class of the entity as a parameter to be used in the generic operations.


Now, let’s look at an example implementation of this DAO, for a Foo entity:


public class FooDAO extends AbstractHibernateDAO< Foo > implements IFooDAO{

   public FooDAO(){
      setClazz(Foo.class );

4. Conclusion


This article covered the configuration and implementation of the persistence layer with Hibernate and Spring.


The reasons to stop relying on templates for the DAO layer was discussed, as well as possible pitfalls of configuring Spring to manage transactions and the Hibernate Session. The final result is a lightweight, clean DAO implementation, with almost no compile-time reliance on Spring.

讨论了停止依赖DAO层模板的原因,以及配置Spring来管理事务和Hibernate Session可能存在的陷阱。最后的结果是一个轻量级的、干净的DAO实现,几乎没有对Spring的编译时依赖。

The implementation of this simple project can be found in the github project.

这个简单项目的实现可以在github 项目中找到。