The initial rather lengthy introduction to this article examined the battle between the two major camps of webapp developers (which could be described as "Scripted" vs. "Coded") in more depth than anybody who came here for a quick tutorial would be interested in. However, they would have gained from it the following points:

  • RSF aims to bridge the gap between the scripted and coded camps, allowing styles similar to scripted webapps to be used for simpler or early-stage projects, with a clear transition path to mature coded solutions.
  • In this tutorial we will demonstrate the full power of the Java open source community in the form of Spring, Hibernate and Maven brought to bear on the simple Ruby on Rails "cookbook" application, while seeing these sometimes uneasy partners cooperate seamlessly in an environment based on pure HTML templates and XML configuration files. In fact, this application will be implemented without one single line of Java code . Yes, you heard that right!

This sample will follow the "Rolling with Ruby on Rails" sample app, implementing the same functionality in a Java environment. Skip straight to page 4 to see the pure Java version of the app - the initial development uses the XML strategy for component definition.

The RSF SVN repository includes several versions of this project, which show off different styles of working with RSF.

Project nameDescription
HibernateCookbook-basicMost basic project defining one entity (Recipe) together with static XML and HTML views. Suitable for copying to use as a "base project" for new RSF-Hibernate projects
HibernateCookbook-xmlcategory"Completed" project with the final functionality of the ROR project, using XML producers. Two entities, "Recipe" and "Category", shows how to use RSF (HTML) selection controls to operate directly on a Hibernate bean model.
HibernateCookbook-javacategoryA reworking of the finished "category" project, using pure Java ViewProducers rather than XML files, the path that might be taken for a more complex project. This project is actually factored into three Maven artifacts, category-datamodel, javacategory-code and javacategory-webapp - consult page 5 for details.
HibernateCookbook-xslShows the "basic" project, autogenerated from nothing but the Hibernate .hbm mapping files using XSL transforms. A suitable strategy to "kick-start" a project with a complex entity model, or where it is to be prototyped or maintained by non-developers. (TBA)

In fact, while the XML strategy for defining view components can offer crucial flexibility in some situations, it's imagined that the majority of RSF users will want to go with pure Java producers. XML producers and Java producers are generally in one-for-one correspondance - we will first generate the complete app using the XML style, and then on the final page rework it in a Java form that is more compact and efficient. Note that view producers will in general be the only dependence in application code on the RSF framework, and the fact that these generally define "pure data" that could equally well be represented in XML indicates that this is a very light kind of dependence.

First, choose a database#

Like the ROR example, we will begin by installing a database. We choose MySQL since it is common in production environments, and is now quite straightforward to install. Other possibilities are Postgres, or for low-profile deployments there is Apache's excellent Derby (formerly IBM Cloudscape). Hibernate has drivers for all popular databases, so take your pick.

The most recent version of MySQL at the time of writing was 5.0.18 - we used the Windows Essentials distribution. Using a different database is just a matter of changing Hibernate configuration files.

The sample code for this project in SVN assumes that the database was set up with an "anonymous account" option.

We use Hibernate together with Spring (naturally, for a Spring-based framework such as RSF), so instead of using Hibernate's property file syntax, we configure Hibernate using two beans in the application's applicationContext.xml file, being a dataSource specifying details of the database connection at the JDBC level, and the Hibernate sessionFactory.

The two beans required to connect to our default anonymous MySQL instance are reproduced below, taken from the full applicationContext.xml file:

 <!--  Configure the Hibernate SessionFactory bean with a basic data source
    pointing at our database  -->
  <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName">
      <value>com.mysql.jdbc.Driver</value>
    </property>
    <property name="url">
      <value>jdbc:mysql://localhost:3306/hibernatecookbook</value>
    </property>
    <property name="username">
      <value></value>
    </property>
    <property name="password">
      <value></value>
    </property>
  </bean>

  <bean id="sessionFactory"
    class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
    <property name="dataSource">
      <ref bean="dataSource" />
    </property>
    <property name="mappingLocations">
      <value>classpath:conf/**.hbm.xml</value>
    </property>
    <property name="hibernateProperties">
      <props>
        <prop key="hibernate.dialect">
          net.sf.hibernate.dialect.MySQLDialect
        </prop>
        <prop key="hibernate.show_sql">true</prop>
        <!-- Always drop and recreate the database schema on startup -->
        <prop key="hbm2ddl.auto">update</prop>
      </props>
    </property>
    <!-- Always drop and recreate the database schema on startup -->
    <property name="schemaUpdate"><value>true</value></property>
  </bean>

Deploying a Hibernate app requires a great deal more in the way of supporting libraries than a simple RSF app. Luckily, maven makes this easy - rather than figure this out from scratch, simply use the standard project.xml file for our basic project which will automatically populate your Maven repository and deployed project with the correct jars. I have also usefully commented the purposes and requirers of each of the dependencies.

We use Hibernate 2.x since the Hibernate 3.x toolset is still unstable (3.1 beta 4 at time of writing), and crucially is lacking support for Maven 1.x in the hbm2java task we will use in the next section.

In the beginning, there was the .hbm file#

While the ROR version of this app is built directly on the database schema, we will take a step backwards in abstraction and take advantage of the considerable insulation and portability that Hibernate offers us. Moving your app to another database and environment is as easy as changing your Hibernate configuration file - putting first-class support for a vast plethora of second-level cache and Enterprise architectures and virtually every popular database dialect within easy reach. By comparison, ROR's "ActiveRecord" ORM solution while initially slick, is ultimately much more limited. While being "configuration-free" as ROR advertises brings startup time down to zero, later on in a project the lack of explicitness will bite with a vengeance - browse over to The Persistence Showdown for a lowdown on the pros and cons. RSF is "as configuration free" as possible, but no more free than that.

Anyone needing a quick start with Hibernate could consult this tutorial by Michael Gloegl, the ultimate reference of course being the Hibernate documentation.

Hibernate is designed with a very broad range of workflows in mind, as regards specification and construction of the schema. The following ONJava article by John Ferguson Smart outlines a few of them - we will choose the last of those he mentions, based on using Hibernate's ".hbm" mapping file as the starting point and authoritative specification of our data model. This approach has many advantages, which Johnathan outlines in some detail.

The .hbm file will tie down once and for all the relationship between Java types and SQL, so let us write it with no further ado. If you are building this app from scratch, download, unpack and rename the "HelloWorld" app and type the following into /WEB-INF/cookbook.hbm.xml -

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
  "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
  "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping package="uk.org.ponder.rsf.cookbook">

  <class name="Recipe" table="recipe">
    <id name="id" type="int">
      <generator class="native" />
    </id>
    <property name="title" type="string" not-null="true" length="255" />
    <property name="description" type="string" length="255" />
    <property name="date" type="date" />
    <property name="instructions" type="string" />
  </class>

</hibernate-mapping>

This specifies the database schema that will be in effect by the time you reach figure 34 of page 3 of the ROR example, although in a somewhat more portable way.

The next step is to embody this schema at both ends - both as Java code and as a database table. Luckily, Hibernate comes supplied with tools to perform this automatically, making good on our promise of IDE-free development. The tool to automatically generate Java classes from .hbm is part of the standard Hibernate distribution called hbm2java, for which there is useful tutorial at OnJava, which explains the basic idea. Ant is fully integrated with Maven 1.x, so we can invoke the hbm2java task with the following maven.xml definition:

  <goal name="generate-hibernate-javamodel">
    <j:set var="hibernate.cfg.xml"
      value="${basedir}/src/conf/hibernate.cfg.xml" />
    <j:set var="generated.hbm" value="${basedir}/src/conf/" />
    <j:set var="generated.sources"
      value="${basedir}/src/generated-java/" />
    <echo>${generated.sources}</echo>

    <ant:taskdef name="hbm2java"
      classname="net.sf.hibernate.tool.hbm2java.Hbm2JavaTask"
      classpathref="maven.dependency.classpath" />

    <ant:hbm2java output="${generated.sources}">
      <ant:fileset dir="${generated.hbm}">
        <ant:include name="**/*.hbm.xml" />
      </ant:fileset>
    </ant:hbm2java>
  </goal>

This task is set up to read all hibernate mapping files from our conf directory and output corresponding .java files for each entity into the generated-java directory.

Invoke it using the command line

maven generate-hibernate-javamodel
issued from the project root.

Voila!! The only java code we will use in our project has just been automatically written for us.

Read on to see how we will generate our first views and templates.


Head - Hibernate Cookbook
Page 1 - Query beans, templates and views
Page 2 - Switches, Replicators and transit beans
Page 3 - The main app - entity selectors and Javascript
Page 4 - Let's hear that one more time - this time in Java

Add new attachment

Only authorized users are allowed to upload new attachments.

List of attachments

Kind Attachment Name Size Version Date Modified Author Change note
png
MySQL-install.png 48.6 kB 1 19-Jul-2006 09:36 AntranigBasman
« This page (revision-) was last changed on 11-Jan-2007 13:34 by UnknownAuthor