Me too. Unfortunately, I’m finding the learning curve just a bit steep – or maybe it’s just that my brain is not wired the right way. I like to start with the simplest example that does something and then start playing from there. The examples in the Hibernate documentation weren’t quite what I was looking for. For one thing, they all seemed to run inside an App Server. So here is my version of a simple Hibernate application.
Let’s start with some book keeping. I’m using Java 1.4.1_01 on Mac OS X, Ant 1.5.1, Hibernate 2.0.1, and HSqlDB 1.7.1. I chose HSqlDB because I would like to run an in-process database at some point. Although I haven’t tried any other databases, I would expect good results with any other database known to Hibernate. And I would also expect good results with closely related versions of Java and Ant. If you are in a hurry to play, then you can grab the example distribution and go to town (but see this warning first).
Now, on to my Ant build file.
- It starts with two properties that specify the location of the hibernate distribution and the jdbc driver – these should be the only properties that you need to change for your system.
- The directory hierarchy consists of 3 directories: src-dir for Java source, obj-dir for compiled classes, and cfg-dir for all configuration files.
- There are two defined classpaths. The base classpath includes our class files, all the hibernate jar files (I’m not positive that we need them all, but they must be in there for a reason), and the JDBC jar file. And the execution classpath adds our configuration directory in addition to that.
- Finally, be sure to set fork=”true” in your java task; this prevents xml parser conflicts by isolating the hibernate application from the ant application.
1 | <project default="all"> |
And here is where all the action is. We start with a Configuration object that specifies how Hibernate will interact with the underlying Database and add a mapping for the hb.Keyword.class (hibernate will load the file hb/Keyword.hbm.xml from the CLASSPATH). Then we create the Session that acts as a service for persistent objects (via a SessionFactory). Finally, we create a Transaction and save a Keyword object via the Session object.
1 | // |
Now let’s take a look at our configuration files. First, the hibernate.properties file. This specifies that we’ll be using HSqlDB and how the application should connect to HSqlDB server instance.
1 | # |
And finally, the mapping from the hb/Keyword class to the KEYWORDS database table (I’m skipping the Keyword.java file because it’s mostly boilerplate: 2 instance variables, 2 constructors, 2 pairs of get/set methods. Hibernate requires accessors and mutators for persistent fields and a default constructor). The use of the identity generator requires that the KEYWORDS.id column be defined as type identity – you’ll need to look at Hibernate Identity Columns and Sequences to use a database other than HSqlDB.
1 | <?xml version="1.0"?> |
Warning: this application persists keyword objects without regard for any existing persistent keyword objects. Consequently, another row will be added to the database with each execution. We’ll take a look at fixing that later.
With that warning out of the way, you’re ready to get the example distribution and go to town. Here is the output from a sample run on my system (somewhat modified for brevity and format):
1 | $ ant Buildfile: build.xml init: compile: run: [java] Jul 9, 2003 7:42:38 AM net.sf. ... .Environment <clinit> [java] INFO: Hibernate 2.0.1 [java] Jul 9, 2003 7:42:38 AM net.sf. ... .Environment <clinit> [java] INFO: loaded properties from resource hibernate.properties: { ... } [java] Jul 9, 2003 7:42:38 AM net.sf. ... .Environment <clinit> [java] INFO: using CGLIB reflection optimizer [java] Jul 9, 2003 7:42:38 AM net.sf. ... .Environment <clinit> [java] INFO: JVM proxy support: true [java] Jul 9, 2003 7:42:38 AM net.sf. ... .Configuration addClass [java] INFO: Mapping resource: hb/Keyword.hbm.xml [java] Jul 9, 2003 7:42:41 AM net.sf. ... .Binder bindRootClass [java] INFO: Mapping class: hb.Keyword -> keywords [java] Jul 9, 2003 7:42:42 AM net.sf. ... .SessionFactoryImpl <init> [java] INFO: building session factory [java] Jul 9, 2003 7:42:43 AM net.sf. ... .Dialect <init> [java] INFO: Using dialect: net.sf.hibernate.dialect.HSQLDialect [java] Jul 9, 2003 7:42:43 AM net.sf. ... .DriverManagerConnectionProvider configure [java] INFO: Hibernate connection pool size: 2 [java] Jul 9, 2003 7:42:43 AM net.sf. ... .DriverManagerConnectionProvider configure [java] INFO: using driver: org.hsqldb.jdbcDriver at URL: jdbc:hsqldb:hsql:\//localhost [java] Jul 9, 2003 7:42:43 AM net.sf. ... .DriverManagerConnectionProvider configure [java] INFO: connection properties: {user=user, password=user} [java] Jul 9, 2003 7:42:43 AM net.sf. ... .SessionFactoryImpl <init> [java] INFO: Use outer join fetching: false [java] Jul 9, 2003 7:42:43 AM net.sf. ... .SessionFactoryImpl <init> [java] INFO: Use scrollable result sets: true [java] Jul 9, 2003 7:42:46 AM net.sf. ... .SessionFactoryObjectFactory addInstance [java] INFO: no JDNI name configured [java] Jul 9, 2003 7:42:46 AM net.sf. ... .SessionFactoryImpl <init> [java] INFO: Query language substitutions: {} all: BUILD SUCCESSFUL Total time: 18 seconds |
Now that we’re here, I have to say that getting started with Hibernate wasn’t so bad. It just wasn’t obvious that it would turn out to be this simple.
Disclaimer: I don’t claim to be an expert on hibernate. Please send comments and corrections.