Best Way to Inject Hibernate Session by Spring 3

Solution 1:

The Spring Reference suggests this usage:

public class ProductDaoImpl implements ProductDao {

    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public Collection loadProductsByCategory(String category) {
        return this.sessionFactory.getCurrentSession()
                .createQuery(
                    "from test.Product product where product.category=?")
                .setParameter(0, category)
                .list();
    }
}

That way your classes don't have any dependencies to Spring, you just use plain Hibernate.

Solution 2:

A combination of skaffman's post and Sean's plus the use of annotations.

Dao

@Respository("productDao")
public class ProductDaoImpl implements ProductDao {

    @Autowired
        private SessionFactory sessionFactory;

            public Collection loadProductsByCategory(String category) {
                    return this.sessionFactory.getCurrentSession()
                        .createQuery(
                            "from test.Product product where product.category=?")
                        .setParameter(0, category)
                        .list();
        }
}

xml

<beans>

  <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
    <property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/>
    <property name="username" value="sa"/>
    <property name="password" value=""/>
  </bean>

  <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="myDataSource"/>
    <property name="mappingResources">
      <list>
        <value>product.hbm.xml</value>
      </list>
    </property>
    <property name="hibernateProperties">
      <value>
        hibernate.dialect=org.hibernate.dialect.HSQLDialect
      </value>
    </property>
  </bean>

</beans>

Solution 3:

You're over-complicating this.

Please do not use that awful HibernateUtil pattern that keeps popping up in the Hibernate documentation. Spring provides a much, much nicer way of configuring a Hibernate SessionFactory - the LocalSessionFactoryBean (see docs for example usage).

LocalSessionFactoryBean produces a SessionFactory object, which you can inject as a property into your DAO beans.

Spring is happy for you to not use HibernateDaoSupport and HibernateTemplate - there's a section of the docs explaining how to do it nicely.

Solution 4:

The advisable way of using Hibernate is through JPA (hibernate-entitymanager):

@PersistenceContext
private EntityManager entityManager;

and in the applicationContext.xml:

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="yourUnitName" />
    <property name="dataSource" ref="dataSource" /> <!-- needs a data source bean -->
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="databasePlatform" value="${hibernate.dialect}" />
        </bean>
    </property>
</bean>



<bean id="transactionManager" 
  class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

And you'll need a META-INF/persistence.xml