Monday, September 11, 2006

Rolling with Spring and Hibernate, part 1: setup

Now that the Spring 2.0 release is imminent, and we're approaching the final version of JPA with Hibernate being the most prominent implementation, I though it would be interesting to see how the Recipies application know from the excellent "Rolling with Ruby on Rails" article from ONLamp.com could be built on this upcoming stack.

Note that I'm not trying to make neither Rails nor Spring/Hibernate (intentionally) look bad, I think both stacks are very interesting. This particular domain, very-simple-web-application-with-a-quick-start really should be considered Rails' home turf, and I'm trying to determine exactly where the overhead is major, where it's minor, and maybe even where Rails is trailing. I'm also going to point out a few areas where Spring could do better.

This first part is going to describe the development setup I'm using: tools, API:s etc.

I decided to use the following API components:
And these development tools:
WST and SpringIDE are crucial for smooth XML editing, offering code-completion and validation of everything from attribute values (according to XSD) to bean-name references.

Ok, so let's get this party started! First of all, we create a database using these commands in a MySQL promt:

create database 'cookbook' character set 'utf8';
grant all on cookbook.* to 'cookbook'@'localhost' identified by 'cookbook';

Maven lets us create the basic directory structure and a basic pom.xml by running the Quickstart archetype:

mvn archetype:create -DgroupId=se.petrix -DartifactId=cookbook

Unfortunately, a few important directories are missing from this, so we create them manually:

mkdir -p src/main/resources
mkdir -p src/test/resources
mkdir -p src/main/webapp/WEB-INF

The "resource" directories hold stuff that goes into the root of the classpath in the final package. We can also get rid of the App.java and AppTest.java files.

Next, we populate the pom.xml with the API components we've chosen. Rails, of course does not really offer a choice of ORM, templating engine etc, so this is a bit more work. A slightly more advanced archetype could make this a lot easier, by generating a pom.xml with a few more dependencies and common configuration options already in place. I won't go through the entire pom.xml here, but there are a few caveats:
  • We need to set the source and target levels of the Java compiler to 1.5 explicitly, Maven assumes java 1.4.
  • The Hibernate Annotations dependency information is a bit out of date, so we need to exclude the improper dependency and include the correct one.
  • The output directory, which is propagated to Eclipse, is set to inside the web app source folder, to make the feedback cycle as short as possible.

The short feedback cycle is one of Rails' strongest points, and due to the fact that we can't reload classes on the fly in Java - a very popular RFE - we need to reload the entire web app when making a change in a Java file. It's not as bad as it may sound though, reloading is fast and automatic. Changes to Freemarker templates require no reloading, and Spring 2.0 allows you to write beans in script languages such as Groovy, BeanShell or even Ruby, which don't need reloading either.

After this is done, we generate the Eclipse project metadata using Maven:

mvn eclipse:eclipse

One of the benefits of Maven is that you can generate project metadata for many of the biggest IDE's, such as Eclipse, Netbeans and IDEA. In general I think it would be safe to say that IDE support is a lot better for the Spring/Hibernate stack than for Rails, and Maven makes it easy to move between them.

In the next part, we'll start writing our domain model.

No comments: