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.
getProductList() {
package springapp.repository;
import java.util.List;
import org.hibernate.Session;
import springapp.domain.Product;
public class HibernateProductDao implements ProductDao {
public List
List
return products;
}
public void saveProduct(Product prod) {
Session sess = HibernateUtil.getSessionFactory().openSession();
sess.beginTransaction();
sess.saveOrUpdate(prod);
sess.getTransaction().commit();
}
}
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”>
<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>
<!DOCTYPE hibernate-configuration SYSTEM
“http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd”>
<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>
<!–
<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.
Related posts:
- The Part Time Developer 4: Hibernate reverse engineering and JUnit4 I was under the weather toward the end of the...
- The Part Time Developer 5: Spring So now that I'm relatively back in the land of...
- The Part Time Developer 3: Hibernation Mode I got probably a good 3-5 hours in this weekend...
- The Part Time Developer 2: The Beginning So here's a recap of my first week of renewing...
- The Part Time Developer 1: Explanation I apologize for the incoherence of my last post. I...
Related posts brought to you by Yet Another Related Posts Plugin.
Tags: parttimedeveloper
March 22nd, 2008 at 8:42 pm
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.
March 22nd, 2008 at 11:30 pm
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.
August 25th, 2008 at 5:24 am
Hi,
In the Agile Java development world, wildcard imports are a common pattern.
Chris