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.
Hibernate can be configured by creating a property file named hibernate.properties in the src directory and adding its path to the application’s classpath. This file consists of the properties used by Hibernate to connect to database, generate schema, and obtain other database-specific information. To reflect changes in the underlying database into the whole application, only values of the properties in this file need to be modified. Listing 1 shows a simple example. Most of these properties are self-explanatory.
Note: Now Hibernate also can be configured by using a simple XML file named hibernate.cfg.xml, which exists inside the src directory. This file’s structure is very similar to hibernate.properties and has the same functionality. Listing 2 gives an example.
Building an Application with Hibernate
Now, we are ready to build the application. For that, the following steps need to be taken.
- Creating mapping documents
- Generating stub Java classes for persistent objects
- Generating database schema
- Preparing code to initialize and run Hibernate in an appropriate place
These steps are explained in the following sections.
Creating Mapping Documents
Mapping documents are XML documents used to define the persistent objects and contain information about an object’s persistent fields, associations, subclasses, and proxies, if any. One mapping document is created for each persistent object and saved in a file with the name class_name.hbm.xml, where class_name is the name of the object’s class. Listing 3 gives an example of mapping document Event.hbm.xml.
The mapping documents are compiled at application start-up to provide Hibernate with information about the persistent objects’ corresponding classes, their respective structures, to which database table should they be mapped, and how. Hibernate also uses these mapping documents to generate corresponding database schema and stub Java classes for the persistence layer, using inbuilt utilities called SchemaExport and CodeGenerator, respectively.
Generating Stub Classes
This task becomes simpler after mapping documents are created. Stub classes can be created by using Hibernate’s built-in utility CodeGenerator by executing a simple command. Command’s syntax is given below:
java -cp classpath net.sf.hibernate.tool.hbm2java.CodeGenerator options mapping_files
Provide appropriate values for the classpath, options, and mapping_files parameters. Listing 4 shows the stub file generated using the mapping document given in Listing 3.
Generating Database Schema
To generate database schema using Hibernate’s SchemaExport, execute the following command after substituting appropriate values for parameters:
java -cp classpath net.sf.hibernate.tool.hbm2ddl.SchemaExport options mapping_files
Provide appropriate values for the classpath, options, and mapping_files parameters. Figure 1 shows the schema generated using the mapping document given in Listing 3.
Figure 1: Graphical representation of schema generated using the mapping document in Listing 3
Initializing and Running Hibernate
To initialize and run hibernate, the following steps are to be taken:
- Inside an appropriate class, instantiate and populate the desired object to be persisted.
- Obtain the net.sf.hibernate.SessionFactory object using the net.sf.hibernate.cfg.Configuration object at the start of the application.
- Open net.sf.hibernate.Session by calling the openSession() method on the SessionFactory object.
- Save the desired object and close the Session.
Listing 5 shows how to implement the steps described above using a simple class. Now, the application is complete and, when executed, saves the desired objects to the underlying database, i.e. makes them persistent.
Hibernate is a powerful, high-performance, feature-rich and very popular ORM solution for Java. Hibernate facilitates development of persistent objects based on the common Java object model to mirror the underlying database structure. Along with mapping objects to a database, Hibernate also provides advanced data query and retrieval services through HQL, efficient caching, and other optimization techniques and useful built-in utilities for code and schema generation.
By automating the generation of a persistence layer to a large extent, Hibernate helps relieve the developer of up to 95% of common persistence-related coding.
About the Author
Mugdha Chauhan (formerly Mugdha Vairagade) is a senior IT consultant and author. An Open Source supporter, she frequently writes articles and tutorials on useful emerging Open Source projects. Major tech portals including developer.com, IBM developerWorks, CNET Networks, Slashdot, and many eZines regularly publish her work. Her expertise and interests include Java, Linux, XML, wireless application development, and Open Source.