Today I found myself in a familiar position -- needing to write ORM backed code. This was a really simple case actually. I had one new table I needed to add plus a class+DAO to access it from my code. Time to call on my old friend Hibernate.
Perhaps I am "old-fashioned" but I usually like to write DDL first. I can see the logic behind writing an object first and then working from there (object -> mapping -> DDL) but it's just easier for me to write the DDL first. So I wrote that and created my table. Then I fired up Middlegen to create my Hibernate mapping. At that point I paused.
Middlegen is great for generating a Hibernate mapping (hbm) file. I decided not to use this and instead use Java annotations. Hibernate Annotations provides full EJB3 Annotation support for any Hibernate application. So I downloaded it and quickly scanned through some of its documentation. I saw that I needed Hibernate 3.2, so I downloaded the latest version of that 3.2CR3 as 3.2 is not GA yet.
I was already pretty familiar with the EJB3 Annotations as I've been one of the many observers to the evolution of that spec. I was ready to write my annotations, but I still needed a class to annotate. So I went ahead and used Middlegen for that. That required me to generate the hbm file, but I simply discarded it when I was done.
Now I annotated my simple class. I'm using Eclipse 3.2 and it handles annotations very well. I simply write the simple name for the annotation, like @Entity and then I could press ctrl-1 to add the appropriate import statement, just like I would do for a class. It also checked my syntax, so it immediately told me that I didn't need quotes for my nullable attribute when I wrote @Column(name="foo", nullable="false").
Now I had an annotated POJO. Next I wrote the DAO class that accomplished my use cases. They were pretty simple, just two methods. I was using Spring so this was especially easy using its HibernateDaoSupport class.
Next I wrote a simple unit test. I told Eclipse that I wanted a new JUnit test case, and it asked if I wanted to do a 3.x or 4.x test case. I chose 4.x, since I was in an annotative mood. Since this was my first unit test that involved Hibernate Annotations, I decided to keep it as simple as possible and bypass Spring. Thus I simply created my Hibernate session factory in my setUp() method, using the AnnotationConfiguration class, of course.
I ran my test and it failed. Not big surprise, don't all unit tests fail the first time? What was surprising was the error message. I had a stinkin' class not found exception. The class that was not found was org.hibernate.loader.custom.SQLQueryReturn. I looked in my hibernate3.jar and sure enough, it wasn't there!
Luckily it was easy enough to Google for this class and that quickly lead me to a thread on java.net. Turns out while Hibernate Annotations needs Hibernate 3.2, it only works with Hibernate 3.2CR2 not 3.2CR3. In other words, if you download the latest Hibernate and Hibenate Annotations, thye don't work together. I went back to the Hibernate site to download 3.2CR2. I noticed that the general purpose Hibernate download page indicated 3.2CR2 as the latest, even though the home page indicated Hibernate 3.2CR3 was the latest and released on July 6.
So I downloaded 3.2CR2 and used it and ... no problems. I did read on the forums that there definitely were problems with that release, I was just lucky enough not to run into them.
Maybe I should put the annotations on the shelf, for now? I'm guessing that it will be stable well before the code I'm working on will be stable, but it's hard to say given their roadmap...
Blogged with Flock