Feeds

Hibernate Object Relational Mapping (Part 2)

Second in a two-part series by Java Guru John Hunt

  • alert
  • submit to reddit

Intelligent flash storage arrays

Hibernate Object Relational Mapping (Part 1) is here.

Unlike some frameworks, you do not need to do anything special to your objects to allow them to persist via Hibernate. They can be Plain Old Java Objects (or POJO) objects. These objects can follow the JavaBeans conventions and provide setters and getters. Hibernate will then use reflection to obtain the data required to persist the object.

Step 2: Create a hibernate mapping for any Java objects that must be persisted

Although hibernate uses reflection to obtain data, it still needs to know which elements of an object should be persisted, what their types are and where to put the data when it obtains it (e.g. which database table to put the data in). This is defined in another XML file (one per persistent object); which has an hbm.xml extension. For example, if we want to make a Book class persistent, then we would create a Books.hbm.xml file.

Step 3: Add all class mappings to the <session-factory> element of the hibernate.cfg.xml

Next, we need to tell Hibernate about the individual class mapping fields. Adding mapping elements to the hibernate.cfg.xml file, one for each mapping, does this.

Step 4: Create a class to start Hibernate

Although our standard JavaBean classes do not need to know about Hibernate, we do need to start Hibernate up when we need it and to obtain a reference to an appropriate Hibernate Session</> object. This is done by configuring a new SessionFactory object that is initialised using the hibernate.cfg.xml file; and from this session factory Hibernate session objects can be obtained. A Hibernate Session represents a single-threaded unit of work; the SessionFactory is a thread-safe global object, instantiated once. Note that each thread in an application should be supplied with its own session object.

Step 5: Create a test harness to use the persistent class and Hibernate

This of course may be your main application – in this case, it will be a simple test harness class containing a main method.

The final Hibernate application

In this section, we will follow through the steps presented above for a very simple application. We will create a simple Book JavaBean that we want to persist into a table called books (previously set up in MySQL above).

Step 1: Create the Java Objects

We have defined a new Java class called Book in the package uk.co.planetjava.hibernate.bookstore. This Java class has three instance variables id, title, author and price. It also has setter and getter methods for all the variables. There is nothing Hibernate specific about this class. It is presented below.

Step 2: Create a hibernate mapping for any Java objects that must be persisted.

Next, we need to create the Hibernate mapping file for this class. The file will be called Book.hbm.xml and will be saved into the classes directory structure along with the Book.class file. The XML file is presented below:

Note that in this XML file we have mapped the fully qualified name of the class to the MySQL table books. We have also indicated that the instance variable id will be populated by the database itself (remember the id field was specified as auto-increment in the CREATE TABLE SQL statement). We have also specified the types of the various properties to be stored.

Step 3: Add all class mappings to the <session-factory> element of the hibernate.cfg.xml

Next, we need to add this mapping file to the Hibernate Session factories configuration information. This is done via the hibernate.cfg.xml file and is illustrated below. The new mapping element is highlighted and specifies the location of the mapping file (that is it is located along the class path within the uk/co/planetjava/hibernate/bookstore directory).

Step 4: Create a class to start Hibernate

We will create a very simple class to start up Hibernate. In a real application, you will need to think about threading issues in more detail (see http://caveatemptor.hibernate.org/ for an example). Our simple Hibernate initiation class will be called HibernateSessionFactory. It will initialise the SessionFactory class when it is loaded (static blocks are run when a class is first loaded). It will then create a new session upon request via the getHibernateSession() static method. The class is presented below.

Step 5: Create a test harness to use the persistent class and Hibernate

We are now ready to write our test harness class. This class will start up the Hibernate session and obtain a reference to Hibernate via the HibernateSessionFactory class. It will then create an instance of our book class and populate it with data (leaving the id property null). It will then ask Hibernate to save the object using the session.save(Object o) method. We will then close down hibernate. This is illustrated in Figure 9. Note that the only point at which hibernate and the book object come in contact is when hibernate is asked to save the object.

Before we run this example, we should make sure that the log4j.properties file provided with Hibernate is also on our class path. This will allow Hibernate to provide explanatory logging, which will help indicate what Hibernate is doing. This is aided by the print statements included in our main method of the Main class that help to indicate the stages the test application is going through.

You should now be able to run the uk.co.planetjava.hibernate.bookstore.Main application. If you encounter problems, make sure that everything you need is available on your class path.

To check that what we have done has worked properly, return to your MySQL console and perform a select statement on the books table. This is illustrated in Figure 10. As you can see form this, the data entered into the Java object has made its way into the books table. In addition, the id has been automatically generated.

Note to reload the book data into a book object we would use the id as the primary key, the class to load and the get method on a Hibernate Session object, for example:

Book book = (Book) session.get(Book.class, new Integer(1));

Hibernate and Transactions

In the example presented above in this tutorial, we have not used transactions. Under normal circumstances, it would be appropriate to group a series of operations together into a transaction. A transaction is a unit of work that must either be completed or not executed at all. We usually refer to the Hibernate Session as a unit of work because the scope of a Session is exactly that, in almost all cases. To begin a unit of work you open a Session. To end a unit of work you close a Session. Usually you also flush a Session at the end of a unit of work to execute the SQL statements that synchronize the in-memory Session state with the database. However, for mist real world applications this is not enough. Rather it is better to wrap the Hibernate session within a transaction and either commit it on successful completion of all tasks or roll it back if an error occurs. For example, we could modify the earlier example thus:

Transaction trans = sess.beginTransaction();

try { System.out.println("-------------------------------- Save Book");

session.save(book);

trans.commit();

System.out.println("----------- Close the session ");

sess.close();

} catch (Exception exp) {

System.out.println("Rollback the session");

trans.rollback(); }

Indeed this approach is so common that Hibernate expects the environment (in J2EE servers) to disable auto-commit mode, as applications are not executing ad-hoc SQL but a planned sequence of statements.

Where to go next

You have now created and executed your first Hibernate-based Java application. As you can see this application was very simple, but it provides the basics required to work with Hibernate. In the real world, things get more complex with inter-object relationships, database schemas, multiple tables etc. But all those features build from what you have seen here.

For more information on designing efficient relational database storage for your object data (largely a question of normalisation for flexibility and knowing when to denormalise for performance):

The Open Source tutorials on database design here.

An article on database normalisation here.

Another database normalisation tutorial here.

And a summary of database normalisation rules here.

®

Top 5 reasons to deploy VMware with Tegile

More from The Register

next story
Preview redux: Microsoft ships new Windows 10 build with 7,000 changes
Latest bleeding-edge bits borrow Action Center from Windows Phone
Google opens Inbox – email for people too thick to handle email
Print this article out and give it to someone tech-y if you get stuck
Microsoft promises Windows 10 will mean two-factor auth for all
Sneak peek at security features Redmond's baking into new OS
UNIX greybeards threaten Debian fork over systemd plan
'Veteran Unix Admins' fear desktop emphasis is betraying open source
Google+ goes TITSUP. But WHO knew? How long? Anyone ... Hello ...
Wobbly Gmail, Contacts, Calendar on the other hand ...
DEATH by PowerPoint: Microsoft warns of 0-day attack hidden in slides
Might put out patch in update, might chuck it out sooner
Redmond top man Satya Nadella: 'Microsoft LOVES Linux'
Open-source 'love' fairly runneth over at cloud event
prev story

Whitepapers

Choosing cloud Backup services
Demystify how you can address your data protection needs in your small- to medium-sized business and select the best online backup service to meet your needs.
Forging a new future with identity relationship management
Learn about ForgeRock's next generation IRM platform and how it is designed to empower CEOS's and enterprises to engage with consumers.
Security for virtualized datacentres
Legacy security solutions are inefficient due to the architectural differences between physical and virtual environments.
Reg Reader Research: SaaS based Email and Office Productivity Tools
Read this Reg reader report which provides advice and guidance for SMBs towards the use of SaaS based email and Office productivity tools.
Storage capacity and performance optimization at Mizuno USA
Mizuno USA turn to Tegile storage technology to solve both their SAN and backup issues.