Tuesday, February 6, 2007

Hibernate example (Basic)

Table of Content

  1. Introduction
    1. Employee class
    2. HibernateHelper class
    3. CreateEmployee class
    4. hibernate.properties
  2. Running the example
    1. Download the example
    2. Install Java 1.5 and Ant
    3. Database Configuration
    4. Run the Ant build script

Introduction

This Hibernate example maps a simply Java Object (Employee.java) to one database table. This example also creates some instances of this Object and saves them into a database.

The following is the database schema for the Employee Object:

CREATE TABLE EMPLOYEE (
ID BIGINT NOT NULL AUTO_INCREMENT,
NAME VARCHAR(255) NOT NULL,
HIRE TIMESTAMP,
ADDRESS TEXT,
PRIMARY KEY (ID)
);
This example consist of three Java classes which are as follows.


Employee class

The Employee class is a simple POJO which has been setup to be able to be used as an Hibernate Object.

package com.francoisnadeau.test;

import java.util.Date;
import javax.persistence.*;
/**
* A single Employee.
*
* @author Francois Nadeau
* @link http://www.FrancoisNadeau.com
*/


@Entity 1
@Table(name = "EMPLOYEE") 2

public class Employee {
private Long theId;
private String theName;
private Date theHireDate;
private String theAddress;

/**
* The Employee's unique Id.
*
* @return the Employee Id
*/
@Id(generate = GeneratorType.AUTO) 3
public Long getId() { return theId; }
public void setId(Long aId) { theId = aId; }

/**
* The Employee's name.
*
* @return the name
*/
@Basic 4
public String getName() { return theName; }
public void setName(String aName) { theName = aName; }

/**
* The date that the Employee was hired.
*
* @return hired date
*/
@Basic
@Column (name="hire") 5
public Date getHireDate() { return theHireDate; }
public void setHireDate(Date aHireDate) { theHireDate = aHireDate; }
/**
* The employee's address
*
* @return the address
*/
@Basic
public String getAddress() { return theAddress; }
public void setAddress(String aAddress) { theAddress = aAddress; }
}

  1. @Entity
    Hibernate uses Sun's EJB3 Annotation standard to map persistent Objects. Because of this, all Hibernate Objects are treated as Entity Beans.
    Note: Although Hibernate uses the EJB3 standard in this manner, the Objects do not need to be deployed in an EJB container to be used. An interesting benefit of this is that no modifications would be required for this class to be used inside a J2EE compliant server as an Entity Bean .
  2. @Table(name = "EMPLOYEE")
    This annotation defines which table inside the database this Object is to be mapped too.
  3. @Id(generate = GeneratorType.AUTO)
    This annotation defines the primary key for this Object. The following key generators can be used for generating IDs: AUTO, TABLE, IDENTITY, SEQUENCE, or NONE.
  4. @Basic
    This annotation is used to define an Object property. Each properties map to a single field in the database.
  5. @Column (name="hire")
    This annotation is used in combination with @Basic to force a property to be mapped to a different field. The omission of this annotation, in this example, would mean that this property would be mapped to the HireDate field in the database instead of the hire field. This would cause a RunTimeException to be thrown since this field does not exist in the database.

HibernateHelper class

The HibernateHelper class is used to access the Hibernate Sessions. This class is copied from and often referred to in the Hibernate documentation.

package com.francoisnadeau.test;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
/**
* This class is ued to access the Hibernate sessions.
*
* @author Francois Nadeau
* @link http://www.FrancoisNadeau.com
*/
public class HibernateHelper {
private static SessionFactory theSessionFactory;

static {
try {
// Create the SessionFactory
theSessionFactory = new AnnotationConfiguration()
.addPackage("com.francoisnadeau.test") 1
.addAnnotatedClass(Employee.class) 2
.buildSessionFactory(); 3
} catch (Throwable ex) {
theSessionFactory = null;
System.out.print("Error Initializing Hibenrate:\n");
ex.printStackTrace();
}
}

public static Session getSession() throws HibernateException {
return theSessionFactory.openSession(); 4
}
}

  1. .addPackage("com.francoisnadeau.test")
    This method adds package level metadata. This function is required for Hibernate Objects which have been mapped with hbm.xml files. These files where used prior to the release of annotations in Java 1.5 to define the mapping, and are not covered in this example.
  2. .addAnnotatedClass(Employee.class)
    This assigns persistent classes to the Hibernate session. This method must be called for each of the Objects that are to be used by this session.
  3. .buildSessionFactory();
    Construct the SessionFactory which will provide Hibernate sessions to be used to retrieve and store objects in the database.
  4. return theSessionFactory.openSession();
    Retrieve a Hibernate session to be used to retrieve and store Objects which were added to the Configuration.

CreateEmployee class

The CreateEmployee class is a simple program which creates and saves 5 new Employees, and then outputs the number of Employees which are in the database. This is included in the package to demonstrate how the Employee class is to be stored and retrieved from the database using Hibernate.

package com.francoisnadeau.test;

import java.util.List;
import org.hibernate.*;
/**
* @author Francois Nadeau
* @link http://www.FrancoisNadeau.com
*/
public class CreateEmployee {

/**
* Create and save some Employees.
*
* @param args
*/
public static void main(String[] args) {
for (int i = 1; i <>Employee theEmployee = new Employee(); 1
Session theSession = HibernateHelper.getSession(); 2

theEmployee.setName("Employee " + i);

theSession.save(theEmployee); 3
theSession.flush();
theSession.close();
}

Session theSession = HibernateHelper.getSession();
Criteria theCriteria = theSession.createCriteria(Employee.class); 4
List allEmployees = theCriteria.list(); 5

System.out.println("You now have " + allEmployees.size()
+ " Employees.");
}
}

  1. Employee theEmployee = new Employee();
    Creating Hibernate Object and accessing its properties is done in the same manner as any other POJO.
  2. Session theSession = HibernateHelper.getSession();
    A Hibernate session is required to store an Object.
  3. theSession.save(theEmployee);
    This is the call used to save an Object to the database. Other functions such as update and delete are also supported.
  4. Criteria theCriteria = theSession.createCriteria(Employee.class);
    Hibernate criteria are used to retrieve Objects from the database. The code above will retrieve all Employees in the database. The following code would return all Employee objects whose name starts with "Bob":
    Criteria theCriteria = theSession.createCriteria(Employee.class)
    .add( Restrictions.like("name", "Bob%") );
  5. List allEmployees = theCriteria.list();
    The criteria.list() function executes the query on the database, and the results are returned in a java.util.List.

hibernate.properties

The last component for this example is the Hibernate configuration file, which is required for the communicate with the database. Information such as the database location, user-name, and password are entered in this file. If you need more information about this file please refer to the following link.

######################
### Query Language ###
######################
## define query language constants / function names
hibernate.query.substitutions true 1, false 0, yes 'Y', no 'N'
## package imports
#hibernate.query.imports com.kingdomfounder.data

#################
### Platforms ###
#################
## MySQL
hibernate.dialect org.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class com.mysql.jdbc.Driver
hibernate.connection.url jdbc:mysql://localhost/TESTHIBERNATE
hibernate.connection.username aUserName
hibernate.connection.password aPassword

#################################
### Hibernate Connection Pool ###
#################################

hibernate.connection.pool_size 2
hibernate.statement_cache.size 100


Running the example

To run this example follow the following steps:

Download the example

Download and un-pack the example code and binary libraries:

Install Java 1.5 and Ant

Download and install Java 1.5 and apache Ant:
  • Download and install Sun's JDK 1.5 if it is not already installed
  • Download and install the Apache's Ant build tool if it is not already installed

Database Configuration

This example uses MySQL databse since it is Open Source, and freely available.

Once the server is install complete the following commands to load the database schema into the database.

franck@linux:~/code> cd scripts/
franck@linux:~/code/scripts> mysql -u root -p
Enter password: The password is empty by default
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 368 to server version: 4.0.21

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> source dbCreate.sql Execute the sql commands in file
Query OK, 0 rows affected (0.00 sec)

Query OK, 1 row affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Database changed
Query OK, 0 rows affected (0.08 sec)

Run the Ant build script

Open a command prompt and run the following command in the directory which was created when the source code was unpacked.

    ant run.CreateEmployee

The following is the output that will be generated by this command.
franck@linux:~/code> ant run.CreateEmployee
Buildfile: build.xml

init:
[mkdir] Created dir: /home/franck/code/build
[mkdir] Created dir: /home/franck/code/build/classes

resources:
[copy] Copying 4 files to /home/franck/code/build/classes

compile:
[javac] Compiling 3 source files to /home/franck/code/build/classes

jar:
[jar] Building jar: /home/franck/code/build/hibernateTest-1.0.jar

run.CreateEmployee:
[java] Nov 19, 2005 12:15:37 PM org.hibernate.cfg.Environment
[java] INFO: Hibernate 3.1 rc1
[java] Nov 19, 2005 12:15:37 PM org.hibernate.cfg.Environment
[java] INFO: loaded properties from resource hibernate.properties:
{hibernate.connection.driver_class=com.mysql.jdbc.Driver,
hibernate.cglib.use_reflection_optimizer=true, hibernate.dialect=org.hibernate.dialect.MySQLDialect,
hibernate.query.substitutions=true 1, false 0, yes 'Y', no 'N', hibernate.connection.username=aUserName,
hibernate.connection.url=jdbc:mysql://localhost/TESTHIBERNATE, hibernate.connection.password=****,
hibernate.statement_cache.size=100, hibernate.connection.pool_size=2}
[java] Nov 19, 2005 12:15:37 PM org.hibernate.cfg.Environment
[java] INFO: using CGLIB reflection optimizer
[java] Nov 19, 2005 12:15:37 PM org.hibernate.cfg.Environment
[java] INFO: using JDK 1.4 java.sql.Timestamp handling
[java] Nov 19, 2005 12:15:37 PM org.hibernate.cfg.AnnotationConfiguration addPackage
[java] INFO: Mapping package com.francoisnadeau.test
[java] Nov 19, 2005 12:15:37 PM org.hibernate.cfg.AnnotationBinder bindPackage
[java] WARNING: Package not found or wo package-info.java: com.francoisnadeau.test
[java] Nov 19, 2005 12:15:37 PM org.hibernate.cfg.Configuration secondPassCompile
[java] INFO: processing extends queue
[java] Nov 19, 2005 12:15:37 PM org.hibernate.cfg.Configuration secondPassCompile
[java] INFO: processing collection mappings
[java] Nov 19, 2005 12:15:37 PM org.hibernate.cfg.Configuration secondPassCompile
[java] INFO: processing association property references
[java] Nov 19, 2005 12:15:37 PM org.hibernate.cfg.Configuration secondPassCompile
[java] INFO: processing foreign key constraints
[java] Nov 19, 2005 12:15:38 PM org.hibernate.connection.DriverManagerConnectionProvider configure
[java] INFO: Using Hibernate built-in connection pool (not for production use!)
[java] Nov 19, 2005 12:15:38 PM org.hibernate.connection.DriverManagerConnectionProvider configure
[java] INFO: Hibernate connection pool size: 2
[java] Nov 19, 2005 12:15:38 PM org.hibernate.connection.DriverManagerConnectionProvider configure
[java] INFO: autocommit mode: false
[java] Nov 19, 2005 12:15:38 PM org.hibernate.connection.DriverManagerConnectionProvider configure
[java] INFO: using driver: com.mysql.jdbc.Driver at URL: jdbc:mysql://localhost/TESTHIBERNATE
[java] Nov 19, 2005 12:15:38 PM org.hibernate.connection.DriverManagerConnectionProvider configure
[java] INFO: connection properties: {user=aUserName, password=****}
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: RDBMS: MySQL, version: 4.0.21
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: JDBC driver: MySQL-AB JDBC Driver, version: mysql-connector-java-3.1.8 ( $Date: 2005/04/14 20:36:13 $, $Revision: 1.27.4.64 $ )
[java] Nov 19, 2005 12:15:38 PM org.hibernate.dialect.Dialect
[java] INFO: Using dialect: org.hibernate.dialect.MySQLDialect
[java] Nov 19, 2005 12:15:38 PM org.hibernate.transaction.TransactionFactoryFactory
buildTransactionFactory
[java] INFO: Using default transaction strategy (direct JDBC transactions)
[java] Nov 19, 2005 12:15:38 PM org.hibernate.transaction.TransactionManagerLookupFactory
getTransactionManagerLookup
[java] INFO: No TransactionManagerLookup configured (in JTA environment, use of read-write or
transactional second-level cache is not recommended)
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: Automatic flush during beforeCompletion(): disabled
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: Automatic session close at end of transaction: disabled
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: JDBC batch size: 15
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: JDBC batch updates for versioned data: disabled
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: Scrollable result sets: enabled
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: JDBC3 getGeneratedKeys(): enabled
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: Connection release mode: null
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: Maximum outer join fetch depth: 2
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: Default batch fetch size: 1
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: Generate SQL with comments: disabled
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: Order SQL updates by primary key: disabled
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory createQueryTranslatorFactory
[java] INFO: Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
[java] Nov 19, 2005 12:15:38 PM org.hibernate.hql.ast.ASTQueryTranslatorFactory
[java] INFO: Using ASTQueryTranslatorFactory
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: Query language substitutions: {no='N', true=1, yes='Y', false=0}
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: Second-level cache: enabled
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: Query cache: disabled
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory createCacheProvider
[java] INFO: Cache provider: org.hibernate.cache.EhCacheProvider
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: Optimize cache for minimal puts: disabled
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: Structured second-level cache entries: disabled
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: Statistics: disabled
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: Deleted entity synthetic identifier rollback: disabled
[java] Nov 19, 2005 12:15:38 PM org.hibernate.cfg.SettingsFactory buildSettings
[java] INFO: Default entity-mode: POJO
[java] Nov 19, 2005 12:15:38 PM org.hibernate.impl.SessionFactoryImpl
[java] INFO: building session factory
[java] Nov 19, 2005 12:15:38 PM net.sf.ehcache.config.Configurator configure
[java] WARNING: No configuration found. Configuring ehcache from ehcache-failsafe.xml found in the classpath: jar:file:/home/franck/work/95_university/comp601/Project/code/lib/ehcache-1.1.jar!/ehcache-failsafe.xml
[java] Nov 19, 2005 12:15:39 PM org.hibernate.impl.SessionFactoryObjectFactory addInstance
[java] INFO: Not binding factory to JNDI, no JNDI name configured
[java] Nov 19, 2005 12:15:39 PM org.hibernate.impl.SessionFactoryImpl checkNamedQueries
[java] INFO: Checking 0 named queries
[java] You now have 5 Employees.

BUILD SUCCESSFUL
Total time: 5 seconds
Once this program has been executed, you should be able to use the mysql client to select the new Employees which have been created by this program.
franck@linux:~/> mysql -u aUserName -p TESTHIBERNATE
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 366 to server version: 4.0.21

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> select * from EMPLOYEE;
+----+------------+----------------+---------+
| ID | NAME | HIRE | ADDRESS |
+----+------------+----------------+---------+
| 1 | Employee 1 | 20051119121539 | NULL |
| 2 | Employee 2 | 20051119121539 | NULL |
| 3 | Employee 3 | 20051119121539 | NULL |
| 4 | Employee 4 | 20051119121539 | NULL |
| 5 | Employee 5 | 20051119121539 | NULL |
+----+------------+----------------+---------+
5 rows in set (0.00 sec)

2 comments:

Sapphire said...

Great work.

Anonymous said...

nadeaufrancois.blogspot.com is very informative. The article is very professionally written. I enjoy reading nadeaufrancois.blogspot.com every day.
quick cash loans
loans