Spring Framework and Hibernate

Sang Shin, sang.shin@sun.com, Sun Microsystems, www.javapassion.com/j2ee



In this hands-on lab, you are going to build and run sample applications that use Spring framework and Hibernate together.


Expected duration: 100 minutes (excluding homework)




Software Needed

Before you begin, you need to install the following software on your computer. 


OS platforms you can use

Change Log


Lab Exercises


Exercise 0: Perform some setup for the lab


(1.1) Start database server, create a database, make sure Hibernate core library is conifgured


    1. Start the Java DB (Derby) database server if you have not done so yet. 
    2. Create "mydatabase" database if you have not done so yet. 
3. Make sure you have created HibernateCore library, HibernateCore, as described here.



(1.2) Install Spring Framework NetBeans plug-in


1. Make sure you have installed Spring MVC NetBeans plug-in as described here.

Exercise 1: Build and run "SpringHibernateDaoInjection" sample application

In this exercise, you are going to build and run "ready-to-build" sample application. 


(1.1) Open, build, and run "SpringHibernateDaoInjection" sample application

0. Start NetBeans IDE. 
1. Open SpringHibernateDaoInjection NetBeans project. 

2. Add Spring framework library files and commong logging library files to the project.


3. Build and run SpringHibernateDaoInjection project. 


******** Table: events *******
+-------------+--------------------------------+
|     UID       |              NAME                  |
+-------------+--------------------------------+
| 1               | Java Course in Boston     |
| 2               | JavaOne in San Francisco |
+-------------+--------------------------------+

(1.2) Look under the hood of the "SpringHibernateDaoInjection" sample application


1. Main.java

import org.hibernate.*;
import org.hibernate.cfg.Configuration;

public class Main {
   
   
    public static void main(String[] args) {
       
        // Create database table
        HibernateUtil.droptable("drop table events");
        HibernateUtil.setup("create table events ( uid int, name VARCHAR(40), start_Date date, duration int)");
       
        // Create Dao object
        EventSpringDao eventDao = DaoRegistry.getEventDao();
       
        // Create domain objects and save them
        Event event = new Event();
        event.setName("Java Course in Boston");
        eventDao.saveOrUpdate(event);
       
        event = new Event();
        event.setName("JavaOne in San Francisco");
        eventDao.saveOrUpdate(event);
       
        // Display table
        HibernateUtil.checkData("select uid, name from events");
       
    }
   
}

2. DaoRegistry.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.hibernate.SessionFactory;

public class DaoRegistry {
    private static ApplicationContext ctx;
   
    static {
        ctx = new ClassPathXmlApplicationContext("context.xml");
    }
   
    /**
     * Private to make this a singleton.
     */
    private DaoRegistry(){
       
    }
   
    public static SessionFactory getSessionFactory(){
        return (SessionFactory) ctx.getBean("factory", SessionFactory.class);
    }
   
    public static EventSpringDao getEventDao(){
        return (EventSpringDao)ctx.getBean("eventDao", EventSpringDao.class);
    }
}

3. context.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
   
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName">
            <value>org.apache.derby.jdbc.ClientDriver</value>
        </property>
        <property name="url">
            <value>jdbc:derby://localhost:1527/mydatabase</value>
        </property>
        <property name="username">
            <value>app</value>
        </property>
        <property name="password">
            <value>app</value>
        </property>
    </bean>
   
    <bean id="factory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="mappingResources">
            <list>
                <value>Event.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.DerbyDialect</prop>
                <prop key="hibernate.show_sql">false</prop>
            </props>
        </property>
        <property name="dataSource">
            <ref bean="dataSource"/>
        </property>
    </bean>
   
    <bean id="eventDao" class="EventSpringDao">
        <property name="sessionFactory">
            <ref bean="factory" />
        </property>
    </bean>
   
</beans>

4. EventSpringDao.java

import java.util.List;

public class EventSpringDao extends AbstractSpringDao{
    public EventSpringDao(){}
   
    public Event find(Long id){
        return (Event) super.find(Event.class, id);
    }
   
    public void saveOrUpdate(Event event){
        super.saveOrUpdate(event);
    }
   
    public void delete(Event event){
        super.delete(event);
    }
   
    public List findAll(){
        return super.findAll(Event.class);
    }
}

5. AbstractSpringDao.java

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import java.util.List;

public abstract class AbstractSpringDao extends HibernateDaoSupport{

    public AbstractSpringDao() { }

    protected void saveOrUpdate(Object obj) {
        getHibernateTemplate().saveOrUpdate(obj);
    }

    protected void delete(Object obj) {
        getHibernateTemplate().delete(obj);
    }

    protected Object find(Class clazz, Long id) {
        return getHibernateTemplate().load(clazz, id);
    }

    protected List findAll(Class clazz) {
        return getHibernateTemplate().find("from " + clazz.getName());
    }
}

Summary

In this exercise,  you have built and run a ready-to-build-and-run sample application.

                                                                                                                        return to the top




Exercise 2: Build and run "SpringHibernateDaoInjectionOneToMany" sample application

In this exercise, you are going to build and run "ready-to-build" sample application.


(2.1) Open, build, and run "SpringHibernateDaoInjectionOneToMany" sample application

1. Open SpringHibernateDaoInjectionOneToMany NetBeans project. 

2. Resolve a reference problem as described above.
3. Build and run SpringHibernateDaoInjectionOneToMany project. 

******** Table: events *******
+-------------+--------------------------------+
|     UID       |              NAME                  |
+-------------+--------------------------------+
| 1               | Java Course in Boston     |
| 2               | JavaOne in San Francisco |
+-------------+--------------------------------+

******** Table: speakers *******
+-------------+-------------+--------------------------------+--------------------------------+
|     UID       |   EVENT_ID  |            FIRSTNAME           |            LASTNAME            |
+-------------+-------------+--------------------------------+--------------------------------+
| 1               | 1                  | Sang                             | Shin                           |
| 2               | 1                  | Bill                                 | Clinton                        |
| 3               | 1                  | Joan                             | Smith                          |
+-------------+-------------+--------------------------------+--------------------------------+

(2.2) Look under the hood of the "SpringHibernateDaoInjectionOneToMany" sample application


1. Main.java

import java.util.HashSet;

public class Main {
   
   
    public static void main(String[] args) {
        HibernateUtil.droptable("drop table events");
        HibernateUtil.droptable("drop table speakers");
        HibernateUtil.setup("create table EVENTS ( uid int, name VARCHAR(40), start_Date date, duration int)");
        HibernateUtil.setup("create table speakers ( uid int, event_id int, firstName VARCHAR(40), lastName VARCHAR(40))");
       
        // Create Dao object
        EventSpringDao eventDao = DaoRegistry.getEventDao();
       
        // Create domain objects and save them
        Event event = new Event();
        event.setName("Java Course in Boston");
       
        event.setSpeakers(new HashSet());
        event.getSpeakers().add(new Speaker("Sang", "Shin"));
        event.getSpeakers().add(new Speaker("Bill", "Clinton"));
        event.getSpeakers().add(new Speaker("Joan", "Smith"));
        eventDao.saveOrUpdate(event);
       
        event = new Event();
        event.setName("JavaOne in San Francisco");
        eventDao.saveOrUpdate(event);
       
        // Testing code
        HibernateUtil.checkData("select uid, name from events");
        HibernateUtil.checkData("select uid, event_id, firstName, lastName from speakers");
       
    }
   
}

2. context.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
   
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName">
            <value>org.apache.derby.jdbc.ClientDriver</value>
        </property>
        <property name="url">
            <value>jdbc:derby://localhost:1527/mydatabase</value>
        </property>
        <property name="username">
            <value>app</value>
        </property>
        <property name="password">
            <value>app</value>
        </property>
    </bean>
   
    <bean id="factory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="mappingResources">
            <list>
                <value>Event.hbm.xml</value>
                <value>Speaker.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.DerbyDialect</prop>
                <prop key="hibernate.show_sql">false</prop>
            </props>
        </property>
        <property name="dataSource">
            <ref bean="dataSource"/>
        </property>
    </bean>
   
    <bean id="eventDao" class="EventSpringDao">
        <property name="sessionFactory">
            <ref bean="factory" />
        </property>
    </bean>
   
</beans>

3. Event.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
   
    <class name="Event" table="events">
       
        <id name="id" column="uid" type="long" unsaved-value="null">
            <generator class="increment" />
        </id>
       
        <property name="name" type="string" length="100" />
       
        <property name="startDate" column="start_date" type="date" />
        <property name="duration" type="integer" />
       
        <set name="speakers" cascade="all">
            <key column="event_id" />
            <one-to-many class="Speaker" />
        </set>
       
    </class>
</hibernate-mapping>

4. Event.java

import java.io.Serializable;
import java.util.Date;
import java.util.Set;
import java.util.LinkedHashSet;

public class Event implements Serializable {
    private Long id;
    private int duration;
    private String name;
    private Date startDate;
   
    // Event has one-to-many relationship with Speaker
    private Set speakers;
   
    public Event() {
       
    }
   
    public Event(String name) {
        this.name = name;
    }
   
    /**
     * @hibernate.id generator-class="native" column="uid"
     * @return
     */
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
   
    /**
     * @hibernate.property column="name"
     * @return
     */
    public String getName() { return name; }
    public void setName(String name) { this.name = name;   }
   
    /**
     * @hibernate.property column="start_date"
     * @return
     */
    public Date getStartDate() { return startDate; }
    public void setStartDate(Date startDate) { this.startDate = startDate; }
   
    /**
     * @hibernate.property column="duration"
     * @return
     */
    public int getDuration() { return duration; }
    public void setDuration(int duration) { this.duration = duration; }
   
    public void setSpeakers(Set speakers) {
        this.speakers = speakers;
    }
   
    public Set getSpeakers() {
        return speakers;
    }
   
}

Summary

In this exercise,  you have built and run a ready-to-build-and-run "SpringHibernateDaoInjectionOneToMany" sample application.

                                                                                                                        return to the top

Exercise 3: Build and run "SpringHibernateDaoInjectionPropertyPlaceholderConfigurer" sample application

In this exercise, you are going to build and run "ready-to-build" sample application.  You will then build the same application from scratch.


(3.1) Open, build, and run "SpringHibernateDaoInjectionPropertyPlaceholderConfigurer" sample application

1. Open SpringHibernateDaoInjectionPropertyPlaceholderConfigurer NetBeans project. 

2. Resolve a reference problem as described above.
3. Build and run SpringHibernateDaoInjectionPropertyPlaceholderConfigurer project. 


******** Table: events *******
+-------------+--------------------------------+
|     UID     |              NAME              |
+-------------+--------------------------------+
| 1           | Java Course in Boston          |
| 2           | JavaOne in San Francisco       |
+-------------+--------------------------------+

(3.2) Look under the hood of the "SpringHibernateDaoInjectionPropertyPlaceholderConfigurer" sample application


1. context.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
   
    <bean id="propertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location">
            <value>classpath:project.properties</value>
        </property>
    </bean>
   
    <bean id="dataSource"
          class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close">
        <property name="driverClassName">
            <value>${jdbc.driver}</value>
        </property>
        <property name="url">
            <value>${jdbc.url}</value>
        </property>
        <property name="username">
            <value>${jdbc.user}</value>
        </property>
        <property name="password">
            <value>${jdbc.password}</value>
        </property>
    </bean>
   
    <bean id="factory"
          class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="mappingResources">
            <list>
                <value>Event.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.DerbyDialect
                </prop>
                <prop key="hibernate.show_sql">false</prop>
            </props>
        </property>
        <property name="dataSource">
            <ref bean="dataSource" />
        </property>
    </bean>
   
    <bean id="eventDao" class="EventSpringDao">
        <property name="sessionFactory">
            <ref bean="factory" />
        </property>
    </bean>
   
</beans>

2. project.properties

# DB Info
jdbc.driver=org.apache.derby.jdbc.ClientDriver
jdbc.url=jdbc:derby://localhost:1527/mydatabase
jdbc.user=app
jdbc.password=app
jdbc.maxConnections=25

Summary

In this exercise,  you have built and run a ready-to-build-and-run sample application.

                                                                                                                        return to the top


Homework Exercise (for people who are taking Sang Shin's "Java EE Programming online course")


1. The homework is to modify the SpringHibernateDaoInjectionOneToMany project as described below.  (You might want to create a new project by copying the SpringHibernateDaoInjectionOneToMany project.  You can name the homework project in any way you want but here I am going to call it MySpringHibernateDaoInjectionOneToMany.)
2. Send the following files to j2eehomeworks@sun.com with Subject as J2EEHomework-springhibernate.