Hibernate

What is Hibernate? No; it is not that time of the year when people in the Twin Cities of Minneapolis and St. Paul bunker in their homes until early spring. In this blog entry I will attempt to provide a simple definition and a simple example using Java, Hibernate and the MySQL database.

Hibernate ORM (Object-Relational Mapping) is an object-relational mapping framework for the Java language. It provides a framework for mapping an object-oriented domain model to a relational database. Hibernate solves object-relational impedance mismatch problems by replacing direct, persistent database accesses with high-level object handling functions.

Hibernate’s primary feature is mapping from Java classes to database tables; and mapping from Java data types to SQL data types. Hibernate also provides data query and retrieval facilities. It generates SQL calls and relieves the developer from manual handling and object conversion of the result set. Typically Hibernate is used with relational databases (e.g., MySQL, SQL Server). There are additional hibernate frameworks that allow interaction with NoSQL databases (e.g., Cassandra).

Most production code uses relational database to store the state of an object. When the program is restarted or a thread needs to recall an object, developers need to write code to access the database and restore the object. In general this is not a simple operation. Would it not be great to be able to simplify such operations? Hibernate provides such functionality.

In this blog entry I will deal with the INSERT operation which will store in MySQL the object Employee. In a following post I will SELECT the Employee object from the database.

We have the following databases in the MySQL database:

mysql> show databases;

+——————–+

| Database           |

+——————–+

| information_schema |

| demo               |

| indices            |

| joins              |

| mysql              |

| performance_schema |

| sakila             |

| test               |

| webappdemo         |

| world              |

+——————–+

10 rows in set (0.00 sec)

Of interest is the demo database. In the demo database we have the following tables:

mysql> show tables;

+—————-+

| Tables_in_demo |

+—————-+

| employee       |

| pc_parts       |

+—————-+

2 rows in set (0.00 sec)

Of interest is the employee table. The following screen capture illustrates the contents of the employee table:

mysql> select * from employee;

+—-+———–+————+————————+————-+———–+

| id | last_name | first_name | email                  | department  | salary    |

+—-+———–+————+————————+————-+———–+

|  1 | Doe       | John       | john.doe@foo.com       | HR          |  55000.00 |

|  2 | Public    | Mary       | mary.public@foo.com    | Engineering |  75000.00 |

|  3 | Queue     | Susan      | susan.queue@foo.com    | Legal       | 130000.00 |

|  4 | Williams  | David      | david.williams@foo.com | HR          | 120000.00 |

|  5 | Johnson   | Lisa       | lisa.johnson@foo.com   | Engineering |  50000.00 |

|  6 | Smith     | Paul       | paul.smith@foo.com     | Legal       | 100000.00 |

|  7 | Adams     | Carl       | carl.adams@foo.com     | HR          |  50000.00 |

|  8 | Brown     | Bill       | bill.brown@foo.com     | Engineering |  50000.00 |

|  9 | Thomas    | Susan      | susan.thomas@foo.com   | Legal       |  80000.00 |

| 10 | Davis     | John       | john.davis@foo.com     | HR          |  45000.00 |

| 11 | Fowler    | Mary       | mary.fowler@foo.com    | Engineering |  65000.00 |

| 12 | Waters    | David      | david.waters@foo.com   | Legal       |  90000.00 |

+—-+———–+————+————————+————-+———–+

12 rows in set (0.00 sec)

We now execute a simple Java program that uses Hibernate to store an object into the database. A partial screen capture follows:

Hibernate:

/* insert com.john.canessa.hibernate.Employee

*/ insert

into

employee

(last_name, first_name, email, department, salary, id)

values

(?, ?, ?, ?, ?, ?)

We now select all records from the employee table:

mysql> select * from employee;

+—-+———–+————+————————+————-+———–+

| id | last_name | first_name | email                  | department  | salary    |

+—-+———–+————+————————+————-+———–+

|  1 | Doe       | John       | john.doe@foo.com       | HR          |  55000.00 |

|  2 | Public    | Mary       | mary.public@foo.com    | Engineering |  75000.00 |

|  3 | Queue     | Susan      | susan.queue@foo.com    | Legal       | 130000.00 |

|  4 | Williams  | David      | david.williams@foo.com | HR          | 120000.00 |

|  5 | Johnson   | Lisa       | lisa.johnson@foo.com   | Engineering |  50000.00 |

|  6 | Smith     | Paul       | paul.smith@foo.com     | Legal       | 100000.00 |

|  7 | Adams     | Carl       | carl.adams@foo.com     | HR          |  50000.00 |

|  8 | Brown     | Bill       | bill.brown@foo.com     | Engineering |  50000.00 |

|  9 | Thomas    | Susan      | susan.thomas@foo.com   | Legal       |  80000.00 |

| 10 | Davis     | John       | john.davis@foo.com     | HR          |  45000.00 |

| 11 | Fowler    | Mary       | mary.fowler@foo.com    | Engineering |  65000.00 |

| 12 | Waters    | David      | david.waters@foo.com   | Legal       |  90000.00 |

| 13 | Bond      | James      | james.bond@mi6.gov     | Double 0    | 200000.00 |

+—-+———–+————+————————+————-+———–+

13 rows in set (0.00 sec)

Of interest is the last record (id = 13).

The complete list of files used in this example is listed in the following table:

File Description
Employee.java This class implements the Employee object.
InsertEmployee.java Test class used to set up Hibernate and insert the object into the database.
Employee.hbm.xml This XML defines the columns in the employee table in the database.
Hibernate.cfg.xml This XML configures Hibernate, access the database and mapping files.

Following are the contents of the Employee.java source code file:

package com.john.canessa.hibernate;

import java.io.Serializable;

import java.math.BigDecimal;

/**

* POJO (Plain Old Java Object) class

*/

public class Employee implements Serializable {

/**

* added by Eclipse IDE

*/

private static final long serialVersionUID = 1L;

// **** list of database table fields (e.g., fields in demo:employees) ****

private int          id;           // auto increment index

private String       lastName;

private String       firstName;

private String             email;

private String             department;

private BigDecimal   salary;              // java.Math.BigDecimal (not just a double)

/**

* MUST have empty constructor

*/

public Employee() {

}

/**

*

* @return

*/

public int getId() {

return id;

}

/**

* This method sets the id in the object.

* The id field in the database is auto increment.

* @param id

*/

public void setId(int id) {

this.id = id;

}

/**

*

* @return

*/

public String getLastName() {

return lastName;

}

/**

*

* @param lastName

*/

public void setLastName(String lastName) {

this.lastName = lastName;

}

/**

*

* @return

*/

public String getFirstName() {

return firstName;

}

/**

*

* @param firstName

*/

public void setFirstName(String firstName) {

this.firstName = firstName;

}

/**

*

* @return

*/

public String getEmail() {

return email;

}

/**

*

* @param email

*/

public void setEmail(String email) {

this.email = email;

}

/**

*

* @return

*/

public String getDepartment() {

return department;

}

/**

*

* @param department

*/

public void setDepartment(String department) {

this.department = department;

}

/**

*

* @return

*/

public BigDecimal getSalary() {

return salary;

}

/**

*

* @param salary

*/

public void setSalary(BigDecimal salary) {

this.salary = salary;

}

}

One should note that the Employee class must implement Serializable. This is required by Hibernate to be able to stream the object data to and from the database.

The InsertEmployee.java source code follows:

package com.john.canessa.hibernate;

import java.math.BigDecimal;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;

public class InsertEmployee {

/**

* test code

* @param args

*/

public static void main(String[] args) {

SessionFactory sf    = null;

Configuration cfg    = null;

// **** required to use hibernate ****

try {

cfg    = new Configuration();

} catch (Exception ex) {

System.out.println(“main <<< EXCEPTION new Configuration() – ” + ex.getMessage());

System.exit(-1);

}

cfg.configure(“hibernate.cfg.xml”);

// **** ****

try {

sf     = cfg.buildSessionFactory();

} catch (Exception ex) {

System.out.println(“main <<< EXCEPTION cfg.buildSessionFactory() – ” + ex.getMessage());

System.exit(-1);

}

// **** ****

Session s     = sf.openSession();

Transaction tx       = s.beginTransaction();

// **** define a new employee to be inserted into the database ****

Employee employee = new Employee();

employee.setFirstName(“James”);

employee.setLastName(“Bond”);

employee.setDepartment(“Double 0”);

employee.setEmail(“james.bond@mi6.gov”);

employee.setSalary(new BigDecimal(“200000.0”));

// **** save the employee object in the database ****

s.save(employee);

s.flush();           // auto commit was disabled in configuration file

tx.commit();

s.close();

}

}

The import files must be specified to resolve the classes and methods used by Hibernate. The first few lines are mandatory in order to get Hibernate ready for object access (in this case Employee).

The next few lines define the employee fields for the object we will store in the database.

The last four lines save, flush and commit the new record in the database. The last line releases resources used by the Hibernate session. Note that there is no reference to SQL statements. They are all handled by Hibernate.

The contents of the Employee.hbm.xml file follows:

<?xml version=“1.0” encoding=“UTF-8”?>

<!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD 3.0//EN” “http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd”>

<hibernate-mapping>

<class name=com.john.canessa.hibernate.Employee table=“employee”>

<!– **** id is the key in the employee table **** –>

<id name=“id” column=“id” type=“integer”>

<generator class=“assigned”></generator>

</id>

<!– **** rest of fields in the employee table **** –>

<property name=“lastName” column=“last_name” type=“string”></property>

<property name=“firstName” column=“first_name” type=“string”></property>

<property name=“email” column=“email” type=“string”></property>

<property name=“department” column=“department” type=“string”></property>

<property name=“salary” column=“salary” type=“big_decimal”></property>

</class>

</hibernate-mapping>

This file is used to map the fields in the Employee object to the fields in the employee database table. Of interest is the DOCTYPE line. It must be properly formatted. The name property in the class tag must have the full path to the Employee class (com.john.canessa.hibernate.Employee). Failure to do so will not allow Hibernate to locate the class in the project.

The extension (.hbm.xml) of the file is important. The name of the file (e.g., Employee) is up to the developer. In my case I like to use the same name of the object and the same name as the database table.

Finally, the contents of the Hibernate.cfg.xml file:

<?xml version=“1.0” encoding=“UTF-8”?>

<!DOCTYPE hibernate-configuration PUBLIC “-//Hibernate/Hibernate Configuration DTD 3.0//EN” “http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd”>

<hibernate-configuration>

<session-factory>

<!– **** connection to database **** –>

<property name=“hibernate.connection.driver_class”>com.mysql.jdbc.Driver</property>

<property name=“hibernate.connection.url”>jdbc:mysql://localhost/demo</property>

<property name=“hibernate.dialect”>org.hibernate.dialect.MySQLInnoDBDialect</property>

<property name=“hibernate.connection.username”>John</property>

<property name=“hibernate.connection.password”>xxxxxxxx</property>

<!– **** disable autocommit **** –>

<property name=“hibernate.connection.autocommit”>false</property>

<!– **** to display SQL query when running program (need next 3 properties) **** –>

<property name=“show_sql”>true</property>

<property name=“format_sql”>true</property>

<property name=“use_sql_comments”>true</property>

<!– **** for jdbc transaction **** –>

<property name=“hibernate.transaction.factory_class”>org.hibernate.transaction.JDBCTransactionFactory</property>

<!– **** mapping file **** –>

<mapping resource=“employee.hbm.xml”/>

</session-factory>

</hibernate-configuration>

The extension of this file should always be set to .cfg.xml. The name of the file is left up to the developer. In this case I used hibernate.

It is important to make sure that the contents of the DOCTYPE tag are correct. The password property should hold the actual password to the database (the listing shows xxxxxxxx).

The auto commit feature of hibernate has been disable. The reason for this is to ensure that the developer has control enclosing all database operations in transactions. Failure to do so may cause database inconsistencies (e.g., credit an account and debit a different account) if the application / system stops / crashes in the middle of an insert.

The mapping tag is used inform hibernate about the mappings between objects and database schema.

If you have comments or questions regarding this post or any other in this blog, please do not hesitate and send me a message. I will not disclose your name unless you explicitly state so.

John

john.canessa@gmail.com

Follow me on Twitter: @john_canessa

Leave a Reply

Your email address will not be published. Required fields are marked *