Tuesday, September 18, 2007

Hibernate Annotations and You Ain't Gonna Need It

In the last post I showed a Hibernate demo. I wrote it to show how to hook Mayfly to Hibernate, but it also was my first experience with Hibernate Annotations. I have long been hoping that Hibernate Annotations would ease the pain of hibernate, specifically by eliminating the need to keep looking back and forth between XML mapping files, Java code, and database schemas.

Basically, my experience to date is quite positive. The key thing to note about the demo is all the things which aren't there.

This starts with configuration. There is no hibernate.cfg.xml file, no database username and password, no JDBC URL and driver (I guess some of those would come back if we were talking to a database like MySQL as opposed to Mayfly, but the hibernate.cfg.xml wouldn't).

Next, and more importantly, look at Foo. Here we just need an instance variable for each database column, an annotation @Entity at the start, and an annotation @Id on the primary key. Since the instance variables are named the same as the columns, we don't need to specify a mapping between the two. There's no XML mapping file. I also don't bother with getters and setters. I can always add them later (that's why refactoring browsers have "encapsulate field"), and using them only where they are providing some value avoids a huge amount of clutter. (Or to put it more provocatively, "You Ain't Gonna Need Getters and Setters").

Just getting everything into Foo.java, rather than splitting it between Foo.java and Foo.hbm.xml, is a huge win. You can't just control-click over to the XML file (in a browser like Eclipse), and even if you could you'd be looking back and forth rather than just having everything in one place as with annotations.

So positive impressions confirmed. Definitely plan to give annotations a try on a larger project next time I have a choice.

Demo of Mayfly and Hibernate

In April I wrote a bit about hooking Mayfly to Hibernate. Well, I finally got around to writing a demo showing how to hook it all up in a small self-contained example.

The demo is only a few dozen lines of code, but instead of repeating the whole thing here, I'll point out some interesting bits. Each test creates its own Database object, so there is no shared state to clear out between tests. The test then calls the openConnection on Database to get a JDBC connection, which the FooPersistence class then passes to the openSession method of Hibernate.

Here I configure Hibernate by instantiating an AnnotationConfiguration, tell it the dialect (Hibernate can't figure this out from the connection, because it needs the dialect before the openSession call), and registering Foo as an entity. If you configure Hibernate via XML mapping files, that would work too.

That's pretty much all that is needed. The dialect file is currently part of the demo, so copy it from there.