O/R Mapping with Hibernate
Most enterprise applications have to interact heavily with their back-end databases. To make such interactions possible and make them efficient and fast, enterprise application developers create a "persistence layer" between the application and underlying database, which takes care of storing data from application to the database and retrieving it back, alongside updating and deleting it. In J2EE-based enterprise applications, this persistence layer consists of Java classes that map objects to data and vice versa. This layer is often built using JDBC, entity beans, JDO, and so forth.
Persistence Layer: Problems and Solutions
Building a persistence layer is simple, as long as there is a linear relationship between Java objects and the corresponding database (for example: one object field is mapped to one column of corresponding database table). But often, such relationships are difficult to establish as objects or underlying database have complex structures (for example: object of composite type, collections, properties; database tables having foreign key constrain, cascade property.)
Often, while developing a persistence layer, the properties of a back-end database and its schema are assumed to remain constant forever. And based on this assumption, all persistence operations are hard-coded in the application and thus tied to a particular database schema only. This approach costs dearly in terms of time and efforts when the back-end database schema changes at any point of time, which is often the case in a real-life scenario. The change in the database schema results in the whole persistence layer being rewritten, along with possibility of a significant amount of modifications in the application code itself. This is a tedious and time-consuming task.
Also, these persistence layers may tend to be buggy and inefficient.
This is where Hibernate comes in handy. Hibernate is an Open Source object/relational persistence and query framework. Currently in version 2.1.1, Hibernate is an ODMG3 interface and available free for download from hibernate.org with a Lesser GNU Public License (LGPL).
|ODMG3 is a specification developed by the Object Data Management Group (ODMG), a consortium of various vendors and interested parties working to develop portability specifications for object database and object-relational mapping products. This specification facilitates the development of portable applications that could run on more than one product. See link for more info.|
Hibernate helps create persistent objects based on the common Java object model and thus allows persistent objects to have complex structures such as composite types, Collections, and Properties, along with user-defined types. Now these persistent objects can effectively mirror the complex structure of the underlying database schema.
Hibernate relies on "runtime reflection" that gathers information about objects and their respective database mapping at runtime itself, which does away with the hard-coding of object database mapping in the persistence layer. This way, Hibernate generalizes the persistence layer to accommodate any future changes in the underlying database schema with minimal modifications in the persistence layer code.
|Reflection is a feature from core Java that enables Java code to discover information about the fields, methods, and constructors of loaded classes. Reflection allows using reflected fields, methods, and constructors to operate on their underlying counterparts on objects, within security restrictions. See link for more info.|
Hibernate automates generation for the persistence layer to a large extent, by using its built-in utilities called CodeGenerator and SchemaExport, thus reducing the chances of hand-coding bugs considerably. Hibernate also provides an easy-to-use Hibernate Query Language (HQL), a rich query language designed as a "minimal object-oriented extension to SQL." HQL facilitates writing database-type independent queries that are converted to the local SQL dialect of the underlying database at runtime. This approach keeps queries in the code unaffected when an underlying database type changes, say from Oracle to PostgreSQL.
To increase efficiency, Hibernate includes strategies such as making multiple optimizations while interacting with the database, including caching objects, efficient outer join fetching, and executing SQL statements only when needed. The process overhead of Hibernate is said to be less than 10% of the JDBC.
Setting Up Hibernate
- Download the latest version of the Hibernate source code (e.g. file hibernate-2.1.1.zip or hibernate-2.1.1.tar.gz) from SourceForge. Also, see Download Overview at hibernate.org for reference.
- Uncompress the source archive and extract the contents to the desired directory (ideally the application development directory). Now, the given directory will contain Hibernate's own JAR library hibernate2.jar, along with other directories including two important ones, named lib and src respectively. The lib directory contains third-party libraries/APIs necessary for code generation, ODMG, dom4j, logging, and so forth. The src directory will contain the persistence layer's source files.
- Add the respective paths of hibernate2.jar and other JAR libraries inside the lib directory, which are necessary for application development, to the application's classpath.
- Locate the JDBC driver for the database (e.g. db2java.zip for DB2 UDB) to be used and add its path to the global classpath.
Now, Hibernate is ready to develop a persistence layer for the given application. The following sections explore the steps necessary to do so.