Most applications have some need to work with data. Java applications, when running, tend to encapsulate data as networks of interconnected objects, but those objects vanish in a puff of logic when the program ends, so there needs to be some way to store them. And sometimes the data is already "out there" before the application is even written, so there needs to be a way to read it in and represent it as objects. Writing code by hand to perform these tasks is tedious and error-prone, and can represent a major portion of the effort involved in the overall application.
As good object-oriented developers got tired of this repetitive work, their typical tendency towards enlightened laziness started to manifest itself in the creation of tools to help automate the process. When working with relational databases, the culmination of such efforts were object/relational mapping tools.
There have been a variety of such tools, ranging from expensive commercial offerings to the EJB standards built into J2EE. In many cases, however, the tools introduce their own complexity, force the developer to learn detailed rules for using them, and to modify the classes making up their applications to conform to the needs of the mapping system. As the tools evolved to handle ever more rigorous and complex enterprise requirements, the intricacies required to use them started to overwhelm the savings you could obtain by doing so in simpler, common cases. This has led to something of a revolution favoring more lightweight solutions, of which Hibernate is an example.
Hibernate doesn't get in your way; nor does it force you to change the way your objects behave. They don't need to implement any magical interfaces in order to be blessed with the ability to persist. All you need to do is create an XML "mapping document" telling Hibernate the classes you want to be able to store in a database, and how they relate to the tables and columns in that database, and then you can ask it to fetch data as objects, or store objects as data for you. Compared to most of the alternatives, it's almost magical.
There isn't room in an introductory article like this to work through a concrete example of building and using a Hibernate mapping document (that's what the first couple of chapters in my Hibernate: A Developer's Notebook are for, after all). And there are some good examples already on the Web and in the Hibernate online documentation; see "Learning More," on page 2. It really is straightforward, though. Properties in the application objects are associated with appropriate database structures in a simple, natural way.
At runtime, Hibernate reads the mapping document and dynamically builds Java classes to manage the translation between the database and Java worlds. There is a simple, intuitive API in Hibernate to perform queries against the objects represented by the database. To change those objects you just interact with them normally in the program, and then tell Hibernate to save the changes. Creating new objects is similarly simple; you just create them in the normal way and tell Hibernate about them so they can get stored to the database.
The Hibernate API is simple to learn and interacts quite naturally with the flow of your program. You invoke it in sensible places, and it does what you'd like it to. The benefits it brings in terms of automation and code savings greatly outweigh the short time it takes to learn. And you get an additional bonus in that your code doesn't care (or even have to know) what kind of database you're using. My company has had projects forced to change database vendors late in the development process. This can be a horrible mess, but with Hibernate it has required nothing more than a single change to the Hibernate configuration file.
This discussion has assumed that you already had a relational database set up, as well as Java classes to map, through the creation of the Hibernate mapping document. There is a Hibernate "toolset" that works at build time to support different workflows. For example, if you've got the Java classes and mapping document, Hibernate can create (or update) the necessary database tables for you. Or, starting with just the mapping document, Hibernate can generate the data classes for you, too. Or it can reverse engineer your database and classes to sketch out a mapping document for you. There are also some alpha plugins for Eclipse to provide intelligent editing support and graphical access to these tools right from within the IDE.
If you're in a Hibernate 2 environment, fewer of these tools are provided, but there are third-party options available.
Given how cool and flexible Hibernate seems, why would you ever use anything else? Here are a some scenarios to help you make that judgment (and perhaps, by providing some contrast and context, they'll help identify situations where Hibernate is the perfect fit).
If your application has very simple data storage needs--for example, you just want to manage a group of user preference choices--you don't need a database at all, let alone a fancy object-relational mapping system (even one as wonderfully easy to use as Hibernate)! Starting with Java 1.4, there is a standard Java Preferences API that fills this role very nicely. (More on the Preferences API can be found in this ONJava article.)
For people who are already comfortable working with relational databases and know how to craft the perfect SQL query to interact with an enterprise database, Hibernate might seem to get in the way, much like a land yacht with power everything and automatic transmission can irritate a performance-oriented race car driver. If this describes you, if you're on a project team that includes a strong DBA, or are given stored procedures to work with, you might want to investigate iBATIS. The authors of Hibernate themselves identify iBATIS as an interesting alternative. I found it intriguing because we developed a similar (though much less powerful) system in-house for an e-commerce site and we've been using it in other contexts ever since, although after discovering Hibernate we usually favor that for new projects. You might consider SQL-centric solutions like iBATIS to be "inverted" object/relational mapping tools, whereas Hibernate is a more traditional ORM.
Of course, there may be other external factors that mandate a different approach. You might have to use a full-blown EJB architecture (or some other non-plain-objects mapping system) to fit in with an enterprise environment. You may be tailoring code for a platform that provides its own data storage tools, like Mac OS X's Core Data. You may have been handed a storage specification like an XML DTD, which doesn't involve relational databases at all.
But if you're working with a rich object model, and want to be able to store it flexibly, easily, and efficiently (whether or not you're starting with or have decided on using a relational database, as long as that's an option--and with good free databases like MySQL or the Java embeddable HSQLDB available, it ought to always be an option), then Hibernate is probably the way to go. You may be amazed at how much time you save, and how much you love working with it.
The Hibernate project has extensive online documentation that can help orient you and get you started quickly.
The definitive reference is Hibernate in Action, by Christian Bauer and Gavin King. Written by the creators of Hibernate, it gives you a thorough grounding in what you can do with the package, and how to do it right.
My own book, Hibernate: A Developer's Notebook, is another great way to get started quickly. It provides a direct but detailed walkthrough of how to set up Hibernate in a Java project, and how to use some of its most important features. The code examples are currently based on earlier releases of Hibernate and HSQLDB, so if you want them to work without any tweaks (which is the nicest way to get started), you'll need to work with those versions of the software. The basic concepts remain on target, regardless, and I'm hoping to be able to update the book for Hibernate 3 soon.
Another interesting book is Better Faster Lighter Java, by Bruce Tate and Justin Gehtland. This book's pragmatic approach to getting real projects finished in a sane way is one of the reasons Hibernate spiked in popularity. It gives sound advice on how to evaluate and use (or reject) available Java technologies, and mentions both Hibernate and Spring as examples of the right approach.
Finally, "Working with Hibernate in Eclipse" (though it predates the new alpha Hibernate 3 tools, which are shaping up to be far, far cooler) walks through how to use an Eclipse plugin called Hibernate Synchronizer with Hibernate.
James Elliott is a senior software engineer at Singlewire Software, with fifteen years' professional experience as a systems developer.
Return to ONJava.com.
Copyright © 2009 O'Reilly Media, Inc.