Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Get started with Hibernate

Introducing and configuring Hibernate

  • Print
  • Feedback

Page 5 of 5

By now, you can see that before we can start writing any code that uses Hibernate, we must answer this question: How do we get a Session to work with?

Basic configuration

We've looked at an example application and examined Hibernate's core interfaces. To use Hibernate in an application, you need to know how to configure it. Hibernate can be configured to run in almost any Java application and development environment. Generally, Hibernate is used in two- and three-tiered client-server applications, with Hibernate deployed only on the server. The client application is usually a Web browser, but Swing and SWT (Simple Widget Toolkit) client applications aren't uncommon. Although we concentrate on multitiered Web applications, our explanations apply equally to other architectures, such as command line applications. It's important to understand the difference in configuring Hibernate for managed and nonmanaged environments:

  • Managed environment—Pools resources such as database connections and allows transaction boundaries and security to be specified declaratively (that is, in metadata). A J2EE application server such as JBoss, BEA WebLogic, or IBM WebSphere implements the standard (J2EE-specific) managed environment for Java.
  • Nonmanaged environment—Provides basic concurrency management via thread pooling. A servlet container like Jetty or Tomcat provides a nonmanaged server environment for Java Web applications. A standalone desktop or command line application is also considered nonmanaged. Nonmanaged environments don't provide automatic transaction or resource management or security infrastructure. The application itself manages database connections and demarcates transaction boundaries.


Hibernate attempts to abstract the environment in which it's deployed. In the case of a nonmanaged environment, Hibernate handles transactions and JDBC connections (or delegates to application code that handles these concerns).

In managed environments, Hibernate integrates with container-managed transactions and datasources. Hibernate can be configured for deployment in both environments. In both managed and nonmanaged environments, the first thing you must do is start Hibernate. In practice, doing so is very easy: You have to create a SessionFactory from a Configuration.

Creating a SessionFactory

In order to create a SessionFactory, you first create a single instance of Configuration during application initialization and use it to set the location of the mapping files. Once configured, the Configuration instance is used to create the SessionFactory. After the SessionFactory is created, you can discard the Configuration class.

The following code starts Hibernate:

Configuration cfg = new Configuration();
cfg.addResource("hello/Message.hbm.xml");
cfg.setProperties( System.getProperties() );
SessionFactory sessions = cfg.buildSessionFactory();


The location of the mapping file, Message.hbm.xml, is relative to the root of the application classpath. For example, if the classpath is the current directory, the Message.hbm.xml file must be in the hello directory. XML mapping files must be placed in the classpath. In this example, we also use the system properties of the virtual machine to set all other configuration options (which might have been set before by application code or as startup options).

Method chaining
Method chaining is a programming style supported by many Hibernate interfaces. This style is more popular in Smalltalk than in Java and is considered by some people to be less readable and more difficult to debug than the more accepted Java style. However, it's very convenient in most cases.

Most Java developers declare setter or adder methods to be of type void, meaning they return no value. In Smalltalk, which has no void type, setter or adder methods usually return the receiving object. This would allow us to rewrite the previous code example as follows:

SessionFactory sessions = new Configuration()
   .addResource("hello/Message.hbm.xml")
   .setProperties( System.getProperties() )
   .buildSessionFactory();


Notice that we didn't need to declare a local variable for the Configuration. We use this style in some code examples; but if you don't like it, you don't need to use it yourself. If you do use this coding style, it's better to write each method invocation on a different line. Otherwise, it might be difficult to step through the code in your debugger.



By convention, Hibernate XML mapping files are named with the .hbm.xml extension. Another convention is to have one mapping file per class, rather than have all your mappings listed in one file (which is possible but considered bad style). Our "Hello World" example had only one persistent class, but let's assume we have multiple persistent classes, with an XML mapping file for each. Where should we put these mapping files?

The Hibernate documentation recommends that the mapping file for each persistent class be placed in the same directory as that class. For instance, the mapping file for the Message class would be placed in the hello directory in a file named Message.hbm.xml. If we had another persistent class, it would be defined in its own mapping file. We suggest that you follow this practice. The monolithic metadata files encouraged by some frameworks, such as the struts-config.xml found in Struts, are a major contributor to "metadata hell." You load multiple mapping files by calling addResource() as often as you have to. Alternatively, if you follow the convention just described, you can use the method addClass(), passing a persistent class as the parameter:

SessionFactory sessions = new Configuration()
   .addClass(org.hibernate.auction.model.Item.class)
   .addClass(org.hibernate.auction.model.Category.class)
   .addClass(org.hibernate.auction.model.Bid.class)
   .setProperties( System.getProperties() )
   .buildSessionFactory();


The addClass() method assumes that the name of the mapping file ends with the .hbm.xml extension and is deployed along with the mapped class file.

We've demonstrated the creation of a single SessionFactory, which is all that most applications need. If another SessionFactory is needed—if there are multiple databases, for example—you repeat the process. Each SessionFactory is then available for one database and ready to produce Sessions to work with that particular database and a set of class mappings.

Of course, there is more to configuring Hibernate than just pointing to mapping documents. You also need to specify how database connections are to be obtained, along with various other settings that affect the behavior of Hibernate at runtime. The multitude of configuration properties may appear overwhelming (a complete list appears in the Hibernate documentation), but don't worry; most define reasonable default values, and only a handful are commonly required.

To specify configuration options, you may use any of the following techniques:

  • Pass an instance of java.util.Properties to Configuration.setProperties()
  • Set system properties using java -Dproperty=value
  • Place a file called hibernate.properties in the classpath
  • Include <property> elements in hibernate.cfg.xml in the classpath


The first and second options are rarely used except for quick testing and prototypes, but most applications need a fixed configuration file. Both the hibernate.properties and the hibernate.cfg.xml files provide the same function: to configure Hibernate. Which file you choose to use depends on your syntax preference. It's even possible to mix both options and have different settings for development and deployment

A rarely used alternative option is to allow the application to provide a JDBC Connection when it opens a Hibernate Session from the SessionFactory (for example, by calling sessions.openSession(myConnection)). Using this option means that you don't have to specify any database connection properties. We don't recommend this approach for new applications that can be configured to use the environment's database connection infrastructure (for example, a JDBC connection pool or an application server datasource).

About the author

Christian Bauer is a member of the Hibernate developer team and is also responsible for the Hibernate Website and documentation. Bauer is interested in relational database systems and sound data management in Java applications. He works as a developer and consultant for JBoss and lives in Frankfurt, Germany. Gavin King is the founder of the Hibernate project and lead developer. He is an enthusiastic proponent of agile development and open source software. King is helping integrate ORM technology into the J2EE standard as a member of the EJB 3 Expert Group. He is a developer and consultant for JBoss, based in Melbourne, Australia.

Read more about Tools & Methods in JavaWorld's Tools & Methods section.

  • Print
  • Feedback

Resources