An object-centric application is easy to develop and highly
portable across platforms and databases. An object-relational mapper is a
framework used to transform an object view of the data into a relational one,
and provide persistence services. Here, we'll walk through some simple
Hibernate code snippets, and show you how to persist a POJO-Bean, a part of our
MedTracker application, with Hibernate. We'll create a standalone
console-based Hibernate application. We'll use MySQL DB, and, MySQL connector
for Java to connect to the database.
|
Development environment
We begin by downloading the Hibernate distribution from
hibernate.org. Extract the package and place all required libraries in the /lib
directory. Make sure that you also place hibernate3.jar and the connector JAR
file as well. The /src directory contains all the source files, and, the
binaries are placed inside the /bin directory by Ant. Patient.java is an
ordinary POJO-Bean, placed inside the /src directory that we'll persist.
The mapping file
The mapping file tells Hibernate which table in the database it has to
access, and which columns in that table it should use. That's how Hibernate
knows how to load and store objects of the persistent class. It is a map that
relates the tables and columns in the database to the Bean, and then you can ask
it to fetch data as objects, or store objects as data for you. The
patient.hbm.xml code looks as
not-null="true"/> not-null="true"/> not-null="true"/> not-null="true"/> |
At runtime, Hibernate reads the mapping document and
dynamically builds Java classes to manage the translation between the database
and Java Beans. Between the two Hibernate-mapping tags, include a 'class'
element. All persistent entity classes need such a mapping, to a table in the
SQL database. Each instance represents a row in the underlying database table.
The 'id' tag is for the unique identifier property to the table's primary
key. Finally, we include declarations for the persistent properties of the class
in the mapping file with the 'property' tag. Please note that the types we
declare and use in the mapping files are not, as you might expect, Java data
types. They are also not SQL database types. These types are called
Hibernate-mapping types, converters which can translate from Java to SQL data
types and vice versa. Hibernate is flexible to determine the correct conversion
and mapping type itself if the 'type' attribute is not present in the
mapping.
Hibernate uses a mapping file to determine which table/columns in the database to access, and dynamically builds Java classes |
Configuring Hibernate
Hibernate is the layer in your application which connects to the database,
so it needs connection information. The connections are made through a JDBC
connection pool, which are available out-
of-box with Hibernate.
To configure Hibernate, use hibernate.cfg.xml file as shown
in the code that follows.
|
We configure Hibernate's 'SessionFactory'-a global
factory responsible for a particular database. The first four property elements
contain the necessary configuration for the JDBC connection. The 'dialect'
property element specifies the particular SQL variant Hibernate generates.
Hibernate automatically looks for a file called hibernate.cfg.xml in the root of
the classpath, on startup.
Loading and storing objects
Next, we create a new Patient object, and hand it over to Hibernate.
Hibernate takes care of the SQL and executes INSERT on the database. We have to
begin by first creating a SessionFactory. In order to create a SessionFactory,
you first create a single instance of 'Configuration' during application
initialization. Once configured, the Configuration instance is used to create
the SessionFactory. A Session is a single unit of work to shield our code from
the actual underlying transaction system. We use the 'Transaction' API that
is available on the Hibernate Session. The getCurrentSession() method always
returns the current unit of work. The scope of the current unit of work is the
current Java thread that executes our application. A Session begins when it is
first needed, when the first call to getCurrentSession() is made. It is then
bound by Hibernate to the current thread as:
factory=new |
When the transaction ends, either committed or rolled back,
Hibernate also unbinds the Session from the thread and closes it for you. If you
call getCurrentSession() again, you get a new Session and can start a new unit
of work. An important action performed by the Session object is to create an
active connection to the database. We can persist a Bean using the Save function
of the Session object as:
session.beginTransaction(); |
The benefits it brings in terms of automation and code
savings greatly outweigh the short time it takes to learn.
Ant automation
We'll use Apache Ant to automate compilation and running the sample
application. The Ant build script, build.xml is placed at the root of the
development directory structure. Hibernate fires SQL Queries at runtime,
persisting the Bean by populating the database table
Conclusion
Hibernate can easily integrate with other POJO-based frameworks like Spring.
It is free, fast, effective, popular and offers excellent performance and
flexibility. It is less invasive than other O/R mapping frameworks, uses
reflection and runtime bytecode generation, and SQL generation occurs at system
startup. Also it separates business logic from data access code.
Kunal Jaggi