Copyright ©April 2010 by
Russell Bateman and
Etretat Logiciels, LLC.

Permission is granted for any derivational use. You are forbidden only from reposting the files of the tutorial and project without express permission of the author.

                 
 

Hibernate Nitty-gritty:
    —just the facts, ma'am.

last update:

This is the tutorial to run through first before you move on to the ones that will really teach you something. This is because it solidly addresses the most basic aspects of Hibernate from scratch that often get lost or insufficiently addressed in the longer ones concentrating on power issues.

Among topics covered are:

  • Installation of Hibernate JARs
  • hibernate.cfg.xml
  • The POJO
  • The corresponding mapping file to the POJO

Hibernate will be a turning point in your career. Once you begin to Hibernate, you'll never wake up.

Table of Contents

Introduction to Hibernate
Useful links and books...
Installation of Hibernate JARs
JDBC connector
Slf4j library
Eclipse-based development tools
Our project...
The configuration file: hibernate.cfg.xml
The POJO
The corresponding mapping file to the POJO
The application main()
Running the application
What if I don't see the above?
Some errors you'll see
Where to go from here?
Appendix: Divers notes
Adding Javadoc for Hibernate
Appendix: Some terms

Introduction to Hibernate

Hibernate is a data persistence framework for use in Java (and by code written in still other languages).

Hibernate's purpose is to abstract schema from any database into a Java format for consumption by code thereby isolating the business data from the actual workings of the code.

This means that the result of a query is an instance of a class or a set or collection of instances and not mere rows.

BIG WARNING: You must be VERY careful when using a tutorial off the web to learn Hibernate. There is much XML involved. Often, the authoring tool used to get the article to the web substitutes fancy characters for syntactically crucial contructions and individual characters, especially double-quotes, single-quotes and hyphens. If you get these wrong, an editor such as the one in Eclipse will give you funny colors and you should realize this. However, if you do not, you'll tear your hair out as Hibernate rejects your configuration file and mapping files.

For this reason, I'm writing this tutorial not to demonstrate the power of Hibernate or to do anything cool, but only to help you get the nuts and bolts of your tool stack, the supporting configuration and a very minimal example in place ready to enjoy a more legitimate tutorial.

Useful links and books...

There are many books on Hibernate, but widely acclamined as the Bible on this topic is:

Bauer, Christian and King, Gavin, Java Persistance with Hibernate, 904 pages, November, 2006, Manning Publications, Greenwich, Connecticut.

 

Installation of Hibernate JARs

To set up the Hibernate user library in Eclipse, go to either of the sites below. As this tutorial ages, you'll want to go to the Hibernate site and click on Downloads, then on distribution bundles.

Download and unzip somewhere rather permanent in your development filesystem. For me this sort of thing is at one of:

The user library you create should consist of the following JARs. If you do not know how to constitute a user library for Eclipse, please see Setting up a third-party library: a practical example

(Note: Because I wanted access to Hibernate Javadoc while developing, I went the extra mile in adding its JAR files. See here for how I did this.)

When you include dom4j-x.y.z.jar, realize that other third-party frameworks or utilities, such as XStream, also distribute this JAR to support their code. If you consume one of them, Eclipse will moan about the duplicate and you'll have to toss it out of either Hibernate's or the other utility's user library. (Without having read this observation, you might have invested some time reaching this conclusion—I hope this will save you the trouble.)

JDBC connector

In addition to Hibernate, you also need the JDBC connector for your favorite RDBMS like MySQL, what I'm using here, or another of Derby, PostgreSQL, MS SQL, Oracle, etc.

If you like, you can consult Setting up MySQL in my tutorial on Eclipse and JDBC to see how to set up MySQL and squirrel away the JDBC connector for use in Eclipse.

Slf4j library

Hibernate also consumes the Simple Logging Facade for Java (SLF4J), so you'll need its JAR as well. Please get that by clicking on the icon to the right.


Once I'm set up and running, I find I need the following in Eclipse Build Paths:


Note: In a "real" application, you'd use Maven (or, perhaps, ant and Ivy) to include specific or the latest revisions of all of these libraries in your Eclipse projects.

Another library I failed to show here is Apache log4j. It is required by slf4j which wraps it.

Eclipse-based development tools

There are Eclipse plug-ins from JBoss that might make development easier. However, they are not a must for developing to Hibernate. If you want them, they are had via the following process:

  1. In the Eclipse workbench, pull down the Help menu, choose Install New Software....
  2. Click Add, in Name: type "Hibernate" then entre the update site URL:
    http://download.jboss.org/jbosstools/updates/stable/galileo/
  3. Click the triangle next to Web and Java EE Development, then click the Hibernate Tools box.
  4. Click Next and proceed as for any other Eclipse plug-in.

This adds a Hibernate item to some menus like Window -> Show View -> Hibernate with options to generate configuration and mapping files, etc. and Window -> Preferences -> HQL Editor.

So, you can get the Hibernate tools to generate hibernate.cfg.xml as well as any class-mapping file.

For Hibernate XML files, it creates new file types such as Hibernate Mapping Content-Type and Hibernate Configuration Content-Type. These XML files begin to be decorated specially thus:

Our project...

Our project is little more than an excuse to show how to set up, configure and use Hibernate—a small application to store away and retrieve movie titles of a personal DVD collection. It consists of:

  1. the Hibernate configuration file, hibernate.cfg.xml
  2. a plain old Java object (POJO) or bean to access the data, DvdTitle.java
  3. the mapping file for the bean, DvdTitle.hbm.xml
  4. the application main(), HibernateTest.java

Just set this all up in your Eclipse project as I introduce the files and their content. This presupposes, therefore, that you have some experience in setting up Eclipse projects (if not, please see Setting up Eclipse).

Because I'm only using main() to test and demonstrate the mechanics of Hibernate at a very fundamental level, my project is a plain Java project. (My real DVD catalog application had a browser-based interface and is a Dynamic Web Project.)

The configuration file: hibernate.cfg.xml

The most important item in the configuration file is the mapping element that signals to Hibernate the name(s) of the mapping files. The syntax is simple, as many tutorials intimate, but very crucial to get right.

Create hibernate.cfg.xml in your project's src directory.

Just a note: Maybe it's only me, but I find that I cannot comment out constructs (tag elements) inside this file. When I do, Hibernate seems to pretend I didn't comment them out and I get errors. (I could just be delirious, but it seems to me this is true, so I don't put stuff in and comment it out for later use.)

Here is a sample, the one we're using for this tutorial:

hibernate.cfg.xml:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
  <session-factory>
    <property name="connection.driver_class">com.mysql.jdbc.Driver </property>
    <property name="connection.url">      jdbc:mysql://localhost/DvdCatalog </property>
    <property name="connection.username"> root                     </property>
    <property name="connection.password"> test123                  </property>
    <property name="connection.pool_size">10                       </property>
    <property name="show_sql">            true                     </property>
    <property name="dialect">             org.hibernate.dialect.MySQLDialect</property>
    <property name="hbm2ddl.auto">        update                    </property>

    <!-- mapping files -->
    <mapping resource="com/etretatlogiciels/dvdcatalog/DvdTitle.hbm.xml" />
  </session-factory>
</hibernate-configuration>

In this file, you may run into the problem:

The Processing Instruction Target Matching [xX][mM][lL] is Not Allowed

This indicates something askew with the first few lines of your .xml file. Sometimes it's obvious, sometimes it's not. You should see a little red error marker in the Eclipse editor in the upper-right hand corner (since it affects the first line or two. It's my7sterious; you just have to delete newlines, add them back in again, etc.

If you have failed to add the Connectivity Driver Definition, you will run in this:


    ...ERROR org.hibernate.connection.DriverManagerConnectionProvider - JDBC Driver class not found: com.mysql.jdbc.Driver

The POJO

This is the bean you'd expect to use if, holding data after a query, you had to create a Java object and populate its fields by hand.

Create this Java file in your project's src directory under the package com.etretatlogiciels.dvdcatalog or another of your choosing. You certainly don't have to use mine, but nothing here will work if you don't keep the same one everywhere it matters—throughout these different files.

DvdTitle.java:
package com.etretatlogiciels.dvdcatalog;

public class DvdTitle
{
	static final long serialVersionUID = 1;

	                    // CREATE TABLE dvdtitle(
	private long    id;       // INTEGER AUTO_INCREMENT NOT NULL PRIMARY KEY,
	private boolean bluray;   // BOOLEAN,
	private String  title;    // VARCHAR(255),
	private String  year;     // VARCHAR(4),
	private int     minutes;  // INTEGER,
	private Rating  rating;   // INTEGER,
	private String  url;      // VARCHAR(512),
	private String  stars;    // VARCHAR(1024)
	                    // );


	public long getId()         { return id;    }
	public void setId( long id ){ this.id = id; }

	public boolean isBluray()   { return bluray;  }
	public String  getTitle()   { return title;   }
	public String  getYear()    { return year;    }
	public int     getMinutes() { return minutes; }
	public Rating  getRating()  { return rating;  }
	public String  getUrl()     { return url;     }
	public String  getStars()   { return stars;   }

	public void setBluray ( boolean bluray ) { this.bluray  = bluray;  }
	public void setTitle  ( String title )   { this.title   = title;   }
	public void setYear   ( String year )    { this.year    = year;    }
	public void setMinutes( int minutes )    { this.minutes = minutes; }
	public void setRating ( Rating rating )  { this.rating  = rating;  }
	public void setUrl    ( String url )     { this.url     = url;     }
	public void setStars  ( String stars )   { this.stars   = stars;   }
}

The corresponding mapping file to the POJO

This is the mapping file. With Hibernate, this file and the associated POJO make it so that we don't have to map the data matching our queries into instances of Java classes by hand.

This means lots of work saved, less code to debug, less code to maintain, less superfluous code to get in the way of the reader understanding the application. This is pretty much the whole reason Hibernate exists right there.

(In modern Hibernate and Java, this file can be replaced using annotations in the POJO itself. We're not showing that here, but it's probably the way to go. What we're showing is all of the underlying XML because that was the express purpose of this article.)

Create the mapping file directly alongside the POJO shown above. "identity" will cause the "id" field to be auto-incremented.

DvdTitle.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
		"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
		"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.etretatlogiciels.dvdcatalog">
	<class name="com.etretatlogiciels.dvdcatalog.DvdTitle" table="titles">
		<id name="id" type="long" column="ID" >
            <generator class="identity" />
		</id>

		<property name="bluray">
			<column name="BLURAY" />
		</property>
		<property name="title">
			<column name="TITLE" />
			<!-- type="java.lang.String"
				 not-null="true"
				 length="255"
			  -->
		</property>
		<property name="year">
			<column name="YEAR" />
			<!-- type="java.lang.String"
				 not-null="true"
				 length="4"
			  -->
		</property>
		<property name="minutes">
			<column name="MINUTES" />
		</property>
		<property name="rating">
			<column name="RATING" />
		</property>
		<property name="url">
			<column name="URL" />
			<!-- type="java.lang.String"
				 length="512"
			  -->
		</property>
		<property name="stars">
			<column name="STARS" />
			<!-- type="java.lang.String"
				 length="1024"
			  -->
		</property>
	</class>
</hibernate-mapping>

The application main()

With Hibernate, this file and the associated POJO make it so that we don't have to map the data matching our queries into instances of Java classes by hand.

Note: main() does not have to be in the same package as DvdTitle, but that's how we do it here since the application is so small. Because of this, we don't really have to import it here, but if it were in a different package, we'd need to tell the compiler where it is.

Create HibernateTest.java alongside the POJO and the mapping file (for want of a better place to put it).

HibernateTest.java:
package com.etretatlogiciels.dvdcatalog;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.etretatlogiciels.dvdcatalog.DvdTitle;

public class HibernateTest
{
	public static void main( String[] args )
	{
		Session session = null;

		/* ------------------------------------------------------------------------
		 * Insert a title in the table...
		 * ------------------------------------------------------------------------
		 */
		try
		{
			SessionFactory sessionFactory
							= new Configuration().configure().buildSessionFactory();

			session = sessionFactory.openSession();

			/* Create new instance of Contact and set values in it by reading them
			 * from the object.
			 */
			System.out.println( "Inserting record..." );

			DvdTitle	title = new DvdTitle();

			title.setId     ( 1 );
			title.setBluray ( true );
			title.setTitle  ( "Lord of the Rings: Fellowship of the Rings" );
			title.setYear   ( "2001" );
			title.setRating ( Rating.PG_13 );
			title.setUrl    ( "http://www.lordoftherings.net/" );
			title.setStars  ( "Eliza Wood"
							+ ", " + "Sean Astin"
							+ ", " + "Dominic Monaghan"
							+ ", " + "Billy Boyd"
							+ ", " + "Orlando Gibbons"
							+ ", " + "Viggo Mortenson"
							+ ", " + "Sean Bean"
							+ ", " + "Sir Ian McKellen"
							+ ", " + "John Rhys-Davies"
							);

			session.beginTransaction();
			session.save( title );
			session.getTransaction().commit();

			System.out.println( "Done" );
		}
		catch( Exception e )
		{
			System.out.println( e.getMessage() );
		}
		finally
		{
			// actual DVDTitle insertion will happen at this step
			session.flush();
			session.close();
		}

		/* ------------------------------------------------------------------------
		 * Now do a quick query...
		 * ------------------------------------------------------------------------
		 */
		try
		{
			SessionFactory sessionFactory
							= new Configuration().configure().buildSessionFactory();

			session = sessionFactory.openSession();

			String	QUERY = "from DvdTitle title";
			Query	query = session.createQuery( QUERY );

			System.out.println( "Querying records..." );

			for( Iterator< DvdTitle > it = cast( query.iterate() ); it.hasNext(); )
			{
				DvdTitle	title = ( DvdTitle ) it.next();
				System.out.println( "Got id = " + title.getId()
				                  + ", title = " + title.getTitle() );
			}

			System.out.println( "Done" );
		}
		catch( Exception e )
		{
			System.out.println( e.getMessage() );
		}
		finally
		{
			session.close();
		}
	}

	/**
	 * Bloch says there is no other way to do this, but suppress warnings. It's a
	 * good idea to confine such things to helper methods because SuppressWarnings
	 * isn't a line-by-line thing in Java. And, it's a good thing to proclaim we
	 * know what we're doing here.
	 *
	 * @param < X > - the cooked type; in our case, Iterator< DvdTitle >.
	 * @param o - the raw object in need of a cast.
	 * @return back a cooked object with actual type.
	 */
	@SuppressWarnings( "unchecked" )
	private static final < X > X cast( Object o )
	{
		return ( X ) o;
	}
}

Running the application

The thing about running this over and over again is that it will add the title as many times as you run it. Why? Because it keeps incrementing id which makes it a legitimate, different row in the database table which you can see here in SQuirreL and again later in the console output.


This concludes the tutorial, leaving you hanging because it doesn't really cover queries, updates, deletions, etc. I only promised to get Hibernate up and going in an actual Eclipse project. From here, I suggest you consume better Hibernate tutorials at the links I furnished earlier.

Last, let's run the application to watch it work. As implied, I have done this already several times before. Here's what I see in Eclipse's Console view (I wrapped some of the lines using \).

SLF4J: The requested version 1.5.11 by your slf4j binding is not compatible with [1.5.5, 1.5.6, 1.5.7, 1.5.8] SLF4J: See http://www.slf4j.org/codes.html#version_mismatch for further details. 20 [main] INFO org.hibernate.cfg.Environment - Hibernate 3.5.0-Final 24 [main] INFO org.hibernate.cfg.Environment - loaded properties from resource hibernate.properties: {connection.username=root, \ connection.url=jdbc:mysql://localhost/DvdCatalog, dialect=org.hibernate.dialect.MySQLDialect, hbm2ddl.auto=update, connection.driver_class=com.mysql.jdbc.Driver, \ connection.password=test123, show_sql=true, connection.pool_size=10, hibernate.bytecode.use_reflection_optimizer=false} 28 [main] INFO org.hibernate.cfg.Environment - Bytecode provider name : javassist 46 [main] INFO org.hibernate.cfg.Environment - using JDK 1.4 java.sql.Timestamp handling 224 [main] INFO org.hibernate.cfg.Configuration - configuring from resource: /hibernate.cfg.xml 224 [main] INFO org.hibernate.cfg.Configuration - Configuration resource: /hibernate.cfg.xml 342 [main] INFO org.hibernate.cfg.Configuration - Reading mappings from resource : com/etretatlogiciels/dvdcatalog/DvdTitle.hbm.xml 502 [main] INFO org.hibernate.cfg.HbmBinder - Mapping class: com.etretatlogiciels.dvdcatalog.DvdTitle -> titles 537 [main] INFO org.hibernate.cfg.Configuration - Configured SessionFactory: null 637 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - Using Hibernate built-in connection pool (not for production use!) 637 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - Hibernate connection pool size: 10 638 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - autocommit mode: false 649 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - using driver: com.mysql.jdbc.Driver at URL: jdbc:mysql://localhost/DvdCatalog 649 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - connection properties: {user=root, password=****} 1038 [main] INFO org.hibernate.cfg.SettingsFactory - RDBMS: MySQL, version: 5.1.44-community 1038 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC driver: MySQL-AB JDBC Driver, version: mysql-connector-java-5.1.12 ( Revision: ${bzr.revision-id} ) 1074 [main] INFO org.hibernate.dialect.Dialect - Using dialect: org.hibernate.dialect.MySQLDialect 1081 [main] INFO org.hibernate.engine.jdbc.JdbcSupportLoader - Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4 1084 [main] INFO org.hibernate.transaction.TransactionFactoryFactory - Using default transaction strategy (direct JDBC transactions) 1086 [main] INFO org.hibernate.transaction.TransactionManagerLookupFactory - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional \ second-level cache is not recommended) 1087 [main] INFO org.hibernate.cfg.SettingsFactory - Automatic flush during beforeCompletion(): disabled 1087 [main] INFO org.hibernate.cfg.SettingsFactory - Automatic session close at end of transaction: disabled 1087 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC batch size: 15 1087 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC batch updates for versioned data: disabled 1088 [main] INFO org.hibernate.cfg.SettingsFactory - Scrollable result sets: enabled 1088 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC3 getGeneratedKeys(): enabled 1088 [main] INFO org.hibernate.cfg.SettingsFactory - Connection release mode: auto 1090 [main] INFO org.hibernate.cfg.SettingsFactory - Maximum outer join fetch depth: 2 1090 [main] INFO org.hibernate.cfg.SettingsFactory - Default batch fetch size: 1 1090 [main] INFO org.hibernate.cfg.SettingsFactory - Generate SQL with comments: disabled 1091 [main] INFO org.hibernate.cfg.SettingsFactory - Order SQL updates by primary key: disabled 1091 [main] INFO org.hibernate.cfg.SettingsFactory - Order SQL inserts for batching: disabled 1091 [main] INFO org.hibernate.cfg.SettingsFactory - Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory 1094 [main] INFO org.hibernate.hql.ast.ASTQueryTranslatorFactory - Using ASTQueryTranslatorFactory 1095 [main] INFO org.hibernate.cfg.SettingsFactory - Query language substitutions: {} 1095 [main] INFO org.hibernate.cfg.SettingsFactory - JPA-QL strict compliance: disabled 1095 [main] INFO org.hibernate.cfg.SettingsFactory - Second-level cache: enabled 1095 [main] INFO org.hibernate.cfg.SettingsFactory - Query cache: disabled 1095 [main] INFO org.hibernate.cfg.SettingsFactory - Cache region factory : org.hibernate.cache.impl.NoCachingRegionFactory 1095 [main] INFO org.hibernate.cfg.SettingsFactory - Optimize cache for minimal puts: disabled 1096 [main] INFO org.hibernate.cfg.SettingsFactory - Structured second-level cache entries: disabled 1103 [main] INFO org.hibernate.cfg.SettingsFactory - Echoing all SQL to stdout 1104 [main] INFO org.hibernate.cfg.SettingsFactory - Statistics: disabled 1104 [main] INFO org.hibernate.cfg.SettingsFactory - Deleted entity synthetic identifier rollback: disabled 1105 [main] INFO org.hibernate.cfg.SettingsFactory - Default entity-mode: pojo 1105 [main] INFO org.hibernate.cfg.SettingsFactory - Named query checking : enabled 1105 [main] INFO org.hibernate.cfg.SettingsFactory - Check Nullability in Core (should be disabled when Bean Validation is on): enabled 1177 [main] INFO org.hibernate.impl.SessionFactoryImpl - building session factory 1459 [main] INFO org.hibernate.impl.SessionFactoryObjectFactory - Not binding factory to JNDI, no JNDI name configured 1468 [main] INFO org.hibernate.tool.hbm2ddl.SchemaUpdate - Running hbm2ddl schema update 1468 [main] INFO org.hibernate.tool.hbm2ddl.SchemaUpdate - fetching database metadata 1469 [main] INFO org.hibernate.tool.hbm2ddl.SchemaUpdate - updating schema 1520 [main] INFO org.hibernate.tool.hbm2ddl.TableMetadata - table found: DvdCatalog.titles 1520 [main] INFO org.hibernate.tool.hbm2ddl.TableMetadata - columns: [id, title, minutes, bluray, stars, year, rating, url] 1521 [main] INFO org.hibernate.tool.hbm2ddl.TableMetadata - foreign keys: [] 1521 [main] INFO org.hibernate.tool.hbm2ddl.TableMetadata - indexes: [primary] 1522 [main] INFO org.hibernate.tool.hbm2ddl.SchemaUpdate - schema update complete Inserting record... Hibernate: select max(ID) from titles Done Hibernate: insert into titles (BLURAY, TITLE, YEAR, MINUTES, RATING, URL, STARS, ID) values (?, ?, ?, ?, ?, ?, ?, ?) 17412 [main] INFO org.hibernate.cfg.Configuration - configuring from resource: /hibernate.cfg.xml 17412 [main] INFO org.hibernate.cfg.Configuration - Configuration resource: /hibernate.cfg.xml 17429 [main] INFO org.hibernate.cfg.Configuration - Reading mappings from resource : com/etretatlogiciels/dvdcatalog/DvdTitle.hbm.xml 17546 [main] INFO org.hibernate.cfg.HbmBinder - Mapping class: com.etretatlogiciels.dvdcatalog.DvdTitle -> titles 17550 [main] INFO org.hibernate.cfg.Configuration - Configured SessionFactory: null 17553 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - Using Hibernate built-in connection pool (not for production use!) 17553 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - Hibernate connection pool size: 10 17553 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - autocommit mode: false 17553 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - using driver: com.mysql.jdbc.Driver at URL: jdbc:mysql://localhost/DvdCatalog 17554 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - connection properties: {user=root, password=****} 17587 [main] INFO org.hibernate.cfg.SettingsFactory - RDBMS: MySQL, version: 5.1.44-community 17588 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC driver: MySQL-AB JDBC Driver, version: mysql-connector-java-5.1.12 ( Revision: ${bzr.revision-id} ) 17588 [main] INFO org.hibernate.dialect.Dialect - Using dialect: org.hibernate.dialect.MySQLDialect 17590 [main] INFO org.hibernate.engine.jdbc.JdbcSupportLoader - Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4 17590 [main] INFO org.hibernate.transaction.TransactionFactoryFactory - Using default transaction strategy (direct JDBC transactions) 17590 [main] INFO org.hibernate.transaction.TransactionManagerLookupFactory - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional \ second-level cache is not recommended) 17591 [main] INFO org.hibernate.cfg.SettingsFactory - Automatic flush during beforeCompletion(): disabled 17591 [main] INFO org.hibernate.cfg.SettingsFactory - Automatic session close at end of transaction: disabled 17591 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC batch size: 15 17591 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC batch updates for versioned data: disabled 17591 [main] INFO org.hibernate.cfg.SettingsFactory - Scrollable result sets: enabled 17592 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC3 getGeneratedKeys(): enabled 17592 [main] INFO org.hibernate.cfg.SettingsFactory - Connection release mode: auto 17592 [main] INFO org.hibernate.cfg.SettingsFactory - Maximum outer join fetch depth: 2 17592 [main] INFO org.hibernate.cfg.SettingsFactory - Default batch fetch size: 1 17592 [main] INFO org.hibernate.cfg.SettingsFactory - Generate SQL with comments: disabled 17592 [main] INFO org.hibernate.cfg.SettingsFactory - Order SQL updates by primary key: disabled 17593 [main] INFO org.hibernate.cfg.SettingsFactory - Order SQL inserts for batching: disabled 17593 [main] INFO org.hibernate.cfg.SettingsFactory - Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory 17593 [main] INFO org.hibernate.hql.ast.ASTQueryTranslatorFactory - Using ASTQueryTranslatorFactory 17593 [main] INFO org.hibernate.cfg.SettingsFactory - Query language substitutions: {} 17593 [main] INFO org.hibernate.cfg.SettingsFactory - JPA-QL strict compliance: disabled 17593 [main] INFO org.hibernate.cfg.SettingsFactory - Second-level cache: enabled 17594 [main] INFO org.hibernate.cfg.SettingsFactory - Query cache: disabled 17594 [main] INFO org.hibernate.cfg.SettingsFactory - Cache region factory : org.hibernate.cache.impl.NoCachingRegionFactory 17594 [main] INFO org.hibernate.cfg.SettingsFactory - Optimize cache for minimal puts: disabled 17594 [main] INFO org.hibernate.cfg.SettingsFactory - Structured second-level cache entries: disabled 17594 [main] INFO org.hibernate.cfg.SettingsFactory - Echoing all SQL to stdout 17594 [main] INFO org.hibernate.cfg.SettingsFactory - Statistics: disabled 17595 [main] INFO org.hibernate.cfg.SettingsFactory - Deleted entity synthetic identifier rollback: disabled 17595 [main] INFO org.hibernate.cfg.SettingsFactory - Default entity-mode: pojo 17595 [main] INFO org.hibernate.cfg.SettingsFactory - Named query checking : enabled 17595 [main] INFO org.hibernate.cfg.SettingsFactory - Check Nullability in Core (should be disabled when Bean Validation is on): enabled 17607 [main] INFO org.hibernate.impl.SessionFactoryImpl - building session factory 17633 [main] INFO org.hibernate.impl.SessionFactoryObjectFactory - Not binding factory to JNDI, no JNDI name configured 17634 [main] INFO org.hibernate.tool.hbm2ddl.SchemaUpdate - Running hbm2ddl schema update 17634 [main] INFO org.hibernate.tool.hbm2ddl.SchemaUpdate - fetching database metadata 17634 [main] INFO org.hibernate.tool.hbm2ddl.SchemaUpdate - updating schema 17662 [main] INFO org.hibernate.tool.hbm2ddl.TableMetadata - table found: DvdCatalog.titles 17663 [main] INFO org.hibernate.tool.hbm2ddl.TableMetadata - columns: [id, title, minutes, bluray, stars, year, rating, url] 17663 [main] INFO org.hibernate.tool.hbm2ddl.TableMetadata - foreign keys: [] 17663 [main] INFO org.hibernate.tool.hbm2ddl.TableMetadata - indexes: [primary] 17663 [main] INFO org.hibernate.tool.hbm2ddl.SchemaUpdate - schema update complete Querying records... Hibernate: select dvdtitle0_.ID as col_0_0_ from titles dvdtitle0_ Hibernate: select dvdtitle0_.ID as ID2_0_, dvdtitle0_.BLURAY as BLURAY2_0_, dvdtitle0_.TITLE as TITLE2_0_, YEAR as YEAR2_0_, dvdtitle0_.MINUTES as MINUTES2_0_, dvdtitle0_.RATING \ as RATING2_0_, dvdtitle0_.URL as URL2_0_, dvdtitle0_.STARS as STARS2_0_ from titles dvdtitle0_ where dvdtitle0_.ID=? Got id = 1, title = Lord of the Rings: Fellowship of the Rings Hibernate: select dvdtitle0_.ID as ID2_0_, dvdtitle0_.BLURAY as BLURAY2_0_, dvdtitle0_.TITLE as TITLE2_0_, YEAR as YEAR2_0_, dvdtitle0_.MINUTES as MINUTES2_0_, dvdtitle0_.RATING \ as RATING2_0_, dvdtitle0_.URL as URL2_0_, dvdtitle0_.STARS as STARS2_0_ from titles dvdtitle0_ where dvdtitle0_.ID=? Got id = 2, title = Lord of the Rings: Fellowship of the Rings Hibernate: select dvdtitle0_.ID as ID2_0_, dvdtitle0_.BLURAY as BLURAY2_0_, dvdtitle0_.TITLE as TITLE2_0_, YEAR as YEAR2_0_, dvdtitle0_.MINUTES as MINUTES2_0_, dvdtitle0_.RATING \ as RATING2_0_, dvdtitle0_.URL as URL2_0_, dvdtitle0_.STARS as STARS2_0_ from titles dvdtitle0_ where dvdtitle0_.ID=? Got id = 3, title = Lord of the Rings: Fellowship of the Rings Hibernate: select dvdtitle0_.ID as ID2_0_, dvdtitle0_.BLURAY as BLURAY2_0_, dvdtitle0_.TITLE as TITLE2_0_, YEAR as YEAR2_0_, dvdtitle0_.MINUTES as MINUTES2_0_, dvdtitle0_.RATING \ as RATING2_0_, dvdtitle0_.URL as URL2_0_, dvdtitle0_.STARS as STARS2_0_ from titles dvdtitle0_ where dvdtitle0_.ID=? Got id = 4, title = Lord of the Rings: Fellowship of the Rings Hibernate: select dvdtitle0_.ID as ID2_0_, dvdtitle0_.BLURAY as BLURAY2_0_, dvdtitle0_.TITLE as TITLE2_0_, YEAR as YEAR2_0_, dvdtitle0_.MINUTES as MINUTES2_0_, dvdtitle0_.RATING \ as RATING2_0_, dvdtitle0_.URL as URL2_0_, dvdtitle0_.STARS as STARS2_0_ from titles dvdtitle0_ where dvdtitle0_.ID=? Got id = 5, title = Lord of the Rings: Fellowship of the Rings Done

What if I don't see the above?

Importantly, if you've got some logging turned on and don't see more or less what's above (in red), then you likely are missing a library (JAR) and are just unable to debug deep enough and accurately enough down into Hibernate code to figure this out.

A stupid, but easily likely scenario is a missing dom4j library. Because this is distributed by Hibernate and by other components you might work with, you will have to remove it from one and leave it in another (or build conflicts are reported). Maybe you left it out altogether. It won't necessarily leap out at you that this is the case. Inspect your JARs and those I list here to ensure completeness.

Some errors you'll see

If you see an error parsing your .hbm.xml file like:


    Could not parse mapping document from resource file.hbm.xml

...it's because something's amiss in the definition, perhaps a disconnect between the spelling of some field (property) in this file as compared to the bean? Maybe you've got "award" in the bean and "awards" in the XML file.

If you see:


    Initial SessionFactory creation failed.org.hibernate.HibernateException: Unable to instantiate default tuplizer

...the problem is almost certainly badly constructed getters or setters in your bean. Ask

  1. Do the names match the fields, i.e.: is there a getXxxx() and a setXxxx() to represent field xxxx?
  2.  
  3. Do the types for the getter and setter match the type of the field? You can't return String for an int just because you're trying to compensate cleverly for using INTEGER in your database where what you're really storing is something else (a list of languages or locales or something else you've cleverly encoded, etc.).
  4.  
  5. Is a property definition in your bean (Java code) an int while your .hbm.xml file says:
        <property name="definitionId" type="string">
            <column name="definition_id" />
        </property>
    			

Where to go from here?

To get help, there are various forums and there's Google, of course. One of the best forums is Java Ranch's Object Relational Mapping forum.

Appendix: Divers notes

Adding Javadoc for Hibernate

Since my Hibernate download came with a source code project (it's open source, after all), I was able to enhance Build Path with its whereabouts. While in Build Path -> Libraries, ...

  1. Expand the Hibernate user library by clicking on the triangle to its left.
  2. Expand hibernate3.jar by clicking on the triangle to its left.
  3. Click Edit.
  4. Click External Folder... and navigate to (what path is for me) C:\Users\russ\dev\downloads\hibernate-distribution-3.5.0-Final\project.
  5. Click OK.
  6. Click OK.
  7. Close the Build Path dialog by clicking OK.

If you've read my tutorial on JARs and Eclipse Build Path, you will want to know that in this case, Hibernate's project subdirectory is what is called src by most others.

You can do this for log4j as well.

Appendix: Some terms

These aren't necessarily used in my text, but I wanted to begin a glossary here for whatever use it might be to this or a longer tutorial. The terms are relevant to programming with Hibernate.

 
 
database management system (DBMS) code that controls the creation, maintenance and use of a database
 
object relational mapping (ORM) copying data from (Java) objects to database tables or from tables to (Java) objects, especially when this is done transparently and unintrusively in the application code
 
persistence saving data to an area of storage guaranteed to be available later and independently of the application using it
 
relational database management system (RDBMS) a DBMS based on a relational model, that is, where the relationships between tables are also stored in tables