5 min read

Configuring Hibernate in a Spring context

Spring provides the LocalSessionFactoryBean class as a factory for a SessionFactory object. The LocalSessionFactoryBean object is configured as a bean inside the IoC container, with either a local JDBC DataSource or a shared DataSource from JNDI.

The local JDBC DataSource can be configured in turn as an object of org.apache.commons.dbcp.BasicDataSource in the Spring context:

<bean id="dataSource" 
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>org.hsqldb.jdbcDriver</value>
</property>
<property name="url">
<value>jdbc:hsqldb:hsql://localhost/hiberdb</value>
</property>
<property name="username">
<value>sa</value>
</property>
<property name="password">
<value></value>
</property>
</bean>

In this case, the org.apache.commons.dbcp.BasicDataSource (the Jakarta Commons Database Connection Pool) must be in the application classpath.

Similarly, a shared DataSource can be configured as an object of org.springframework.jndi.JndiObjectFactoryBean. This is the recommended way, which is used when the connection pool is managed by the application server. Here is the way to configure it:

<bean id="dataSource" 
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/HiberDB</value>
</property>
</bean>

When the DataSource is configured, you can configure the LocalSessionFactoryBean instance upon the configured DataSource as follows:

<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
...
</bean>

Alternatively, you may set up the SessionFactory object as a server-side resource object in the Spring context. This object is linked in as a JNDI resource in the JEE environment to be shared with multiple applications. In this case, you need to use JndiObjectFactoryBean instead of LocalSessionFactoryBean:

<bean id="sessionFactory" 
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/hiberDBSessionFactory</value>
</property>
</bean>

JndiObjectFactoryBean is another factory bean for looking up any JNDI resource.

When you use JndiObjectFactoryBean to obtain a preconfigured SessionFactory object, the SessionFactory object should already be registered as a JNDI resource. For this purpose, you may run a server-specific class which creates a SessionFactory object and registers it as a JNDI resource.

LocalSessionFactoryBean uses three properties: datasource, mappingResources, and hibernateProperties. These properties are as follows:

  • datasource refers to a JDBC DataSource object that is already defined as another bean inside the container.
  • mappingResources specifies the Hibernate mapping files located in the application classpath.
  • hibernateProperties determines the Hibernate configuration settings.

We have the sessionFactory object configured as follows:

<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="mappingResources">
<list>
<value>com/packtpub/springhibernate/ch13/Student.hbm.xml</value>
<value>com/packtpub/springhibernate/ch13/Teacher.hbm.xml</value>
<value>com/packtpub/springhibernate/ch13/Course.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.max_fetch_depth">2</prop>
</props>
</property>
</bean>

The mappingResources property loads mapping definitions in the classpath. You may use mappingJarLocations, or mappingDirectoryLocations to load them from a JAR file, or from any directory of the file system, respectively.

It is still possible to configure Hibernate with hibernate.cfg.xml, instead of configuring Hibernate as just shown. To do so, configure sessionFactory with the configLocation property, as follows:

<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="configLocation">
<value>/conf/hibernate.cfg.xml</value>
</property>
</bean>

Note that hibernate.cfg.xml specifies the Hibernate mapping definitions in addition to the other Hibernate properties.

When the SessionFactory object is configured, you can configure DAO implementations as beans in the Spring context. These DAO beans are the objects which are looked up from the Spring IoC container and consumed by the business layer. Here is an example of DAO configuration:

<bean id="studentDao" 
class="com.packtpub.springhibernate.ch13.HibernateStudentDao">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>

This is the DAO configuration for a DAO class that extends HibernateDaoSupport, or directly uses a SessionFactory property. When the DAO class has a HibernateTemplate property, configure the DAO instance as follows:

<bean id="studentDao" 
class="com.packtpub.springhibernate.ch13.HibernateStudentDao">
<property name="hibernateTemplate">
<bean
class="org.springframework.orm.hibernate3.HibernateTemplate">
<constructor-arg>
<ref local="sessionFactory"/>
</constructor-arg>
</bean>
</property>
</bean>

According to the preceding declaration, the HibernateStudentDao class has a hibernateTemplate property that is configured via the IoC container, to be initialized through constructor injection and a SessionFactory instance as a constructor argument.

Now, any client of the DAO implementation can look up the Spring context to obtain the DAO instance. The following code shows a simple class that creates a Spring application context, and then looks up the DAO object from the Spring IoC container:

package com.packtpub.springhibernate.ch13;

public class DaoClient {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"com/packtpub/springhibernate/ch13/applicationContext.xml");
StudentDao stdDao = (StudentDao)ctx.getBean("studentDao");
Student std = new Student();

//set std properties

//save std
stdDao.saveStudent(std);
}
}

LEAVE A REPLY

Please enter your comment!
Please enter your name here