The Part Time Developer 6: Adding Hibernate to the Spring Tutorial

The code formatting in this post is crap. I’ve been fighting with the WordPress code tag all day and I’m giving up. It doesn’t seem to work if I have blank lines and would reposition itself to not include the entire code fragment that I inserted. It also would do away with my tab spacing. So I’m done putting code in here until I can find out how I’m supposed to use it or find a plugin that works better.

So to document this for myself, I thought I’d add an additional section to the Developing a Spring Framework MVC application step-by-step tutuorial. So here’s part 7 of the tutorial: Swapping in Hibernate for Database Persistence.

I didn’t keep track of all the jars I added to the WEB-INF/lib directory, but here’s what I think I added. I probably missed something.
antlr-2.7.6.jar
asm.jar
asm-attrs.jar
c3p0-0.9.1.jar
cglib-2.1.3.jar
commons-collections-2.1.1.jar
commons-dbcp.jar
doms4j-1.6.1.jar
hibernate3.jar

Add the normal HibernateUtil.java to the springapp.repository package. This makes it easier to grab a session object when it’s needed.
package springapp.repository;
import org.hibernate.*;
import org.hibernate.cfg.*;
public class HibernateUtil {
private static SessionFactory sessionFactory;
static {
//Static initializers must catch and wrap any exceptions
try {
sessionFactory = new Configuration().configure()
.buildSessionFactory();
} catch (Throwable ex) {
System.out.println(ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
// Alternatively, you could look up in JNDI here
return sessionFactory;
}
public static void shutdown() {
// Close caches and connection pools
getSessionFactory().close();
}
}

Then we’ll create a Hibernate version of our ProductDao interface, HibernateProductDao.java.

package springapp.repository;
import java.util.List;
import org.hibernate.Session;
import springapp.domain.Product;
public class HibernateProductDao implements ProductDao {
public List
getProductList() {

Session sess = HibernateUtil.getSessionFactory().openSession();
List
products = sess.createQuery(“from Product”).list();
return products;
}
public void saveProduct(Product prod) {
Session sess = HibernateUtil.getSessionFactory().openSession();
sess.beginTransaction();
sess.saveOrUpdate(prod);
sess.getTransaction().commit();
}
}
Now add the necessary hibernate mapping and configuration files:
I added my table mapping file for the product table to war/WEB-INF/classes/springapp/domain directory. I don’t know if this would be the normal place you’d put it. It’s where it should be in a running system. In my previous experience we would put it next to the definition of the product class and then copy it here, but I don’t like having to remember to copy it down when you change it. I’m still looking for an elegant way for doing this.
Product.hbm.xml
<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE hibernate-mapping PUBLIC
“-//Hibernate/Hibernate Mapping DTD 3.0//EN”
http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd”><hibernate-mapping&gt;
<class name=”springapp.domain.Product” table=”products”>
<id name=”id” column=”id”>
<generator class=”native”/>
</id>
<property name=”description”/>
<property name=”price”/>
</class>
</hibernate-mapping>

Here’s the war/WEB-INF/classes/springapp/hibernate.cfg.xml configuration file
<!DOCTYPE hibernate-configuration SYSTEM
http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd”&gt;
<hibernate-configuration>
<session-factory><property name=”hibernate.connection.driver_class”>org.hsqldb.jdbcDriver</property>
<property name=”hibernate.connection.url”>jdbc:hsqldb:hsql://localhost</property>
<property name=”hibernate.connection.username”>sa</property>
<property name=”hibernate.dialect”>org.hibernate.dialect.HSQLDialect</property><!– Use the C3P0 connection pool provider –>
<property name=”hibernate.c3p0.min_size”>5</property>
<property name=”hibernate.c3p0.max_size”>20</property>
<property name=”hibernate.c3p0.timeout”>300</property>
<property name=”hibernate.c3p0.max_statements”>50</property>
<property name=”hibernate.c3p0.idle_test_period”>3000</property>

<!– Show and print nice SQL on stdout –>
<property name=”show_sql”>true</property>
<property name=”format_sql”>true</property>
<property name=”use_sql_comments”>true</property>

<!– List of XML mapping files –>
<mapping resource=”springapp/domain/Product.hbm.xml”/>
</session-factory>
</hibernate-configuration>

Now that all the groundwork as been put into place, the final piece of the puzzle is to use the power of Spring dependency injection and switch the class we’re using for our ProductDao implementation. Modify the applicationContext.xml file and comment out the previous productDao bean and add our new Hibernate version.<bean id=”productDao” class=”springapp.repository.HibernateProductDao”/>
<!–
<bean id=”productDao” class=”springapp.repository.JdbcProductDao”>
<property name=”dataSource” ref=”dataSource”/>
</bean>
–>
And that’s it. Rebuild, redeploy, reload, and browse to the application and things still work as before. Only now we’re using Hibernate for interacting with the database rather than using JDBC and Spring. That’s the power of these tools. If for some reason you need to switch implementations, it’s easy to do. Nothing in your plain Java objects is explicitly tied to a certain technology. By coding to interfaces, it’s easy to switch implementations.

Advertisements

Tags:

3 Responses to “The Part Time Developer 6: Adding Hibernate to the Spring Tutorial”

  1. gojim Says:

    import org.hibernate.*;

    import with a “*”!?!?!?!?!?!?!? This would get you flogged where I work (ok, not flogged, but I’d send out a nasty email for sure)! If you’re doing this work in Eclipse, a simple ctrl-shift-O would take care of all of these for you.

    Every time I see xml mapping files like this I’m happy we moved to EJB3.0 and JPA. 🙂 This is all good stuff though and (as you know) you can do some really cool things with it.

  2. FloydWing Says:

    Oops, that isn’t good, is it? Thanks for the catch.

    I don’t mind the mapping files so much, yet. Of course, I have run into problems for how to represent things the way I want and to get the mappings to work correctly.

  3. Chris Miles Says:

    Hi,

    In the Agile Java development world, wildcard imports are a common pattern.

    Chris

Comments are closed.


%d bloggers like this: