Hibernate Tools Java Naming and Directory Interface

Hibernate tools is a set of utilities used to automatically generate various resources such as

  • Java source files, database schemas and DAO classes from mapping file
  • Mapping file from database schema etc.

It only works either as an Eclipse plug-in or in JBoss Developer Studio or with Apache Ant. When used with Eclipse, it provides an editor to edit mapping files and a console. The editor also supports auto-completion and syntax highlighting and semantic auto-completion for class names, property/field names, table names and column names. The console allows us to configure database connections, provides visualization of classes and their relationships with tables and allows us to execute HQL queries interactively against database and view the query results.

In this section, we shall discuss how to use Hibernate Tools with Ant. If you are new to Ant, you can read its manual from http://ant.apache.org/manuai/index.htmi. We shall create a stand­alone ant build file with the minimum number of required libraries.

1. Using Hibernate Tools with Ant

This section describes how to install and configure Hibernate Tools to work with Apache Ant. If it is not already installed in your machine, download it from https://ant.apache.org/bindownioad. cgi. We downloaded apache-ant-i.9.3-bin.zip and when unzipped in D: drive (in windows), the following directory structure was created. The primary utility ant.bat may be found in bin directory.

To use this utility, either place this directory in your PATH environment variable or use fully qualified path name of this utility.

A set of JAR files is needed to work with Hibernate tools. We downloaded the following JAR files from www.java2s.com: and placed in a directory antlib.

dom4j-1.6.1.jar

freemarker-2.3.19.jar

hibernate3.jar

hibernate-tools.jar

javax.persistence.jar

jtidy-r872-jdk15.jar

log4j-1.2.15.jar

mysql-connector-java-5.1.13.jar

org.apache.commons-logging-1.0.4.jar

slf4j-api-1.5.8.jar

The primary JAR file for Hibernate tools is hibernate-tools.jar. The JAR hibernate- 3.2.2.jar contains core Hibernate and annotation library. The rest of the files are required by Ant build utility. The Hibernate Tools is now ready to work with Ant.

2. Ant Task

The ant runs on a specified XML file containing build information. If none is supplied, ant assumes a file buiid.xmi. A typical structure of this file is shown below:

<project>

</project>

Create an ant task for our Hibernate Tool in the <project> element as follows:

<project>

<path id=”libpath”>

<fileset dir=”antlib” includes=”*.jar”/>

</path>

<taskdef name=”MyTask” classname=”org.hibernate.tool.ant.HibernateToolTask”

classpathref=”libpath” />

</project>

This makes a task called MyTask and the class org.hibernate.tool.ant.HibernateToolTask implements the task. This task can now be used anywhere in the Ant build.xml file:

<project>

<path id=”libpath”>

<fileset dir=”antlib” includes=”*.jar”/>

</path>

<taskdef name=”MyTask” classname=”org.hibernate.tool.ant.HibernateToolTask”

classpathref=”libpath” />

<MyTask destdir=”./target”>

</MyTask>

</project>

The required attribute destDir specifies that directory to be used to place generated files by exporters.

3. Configuring Task

The task, to do its function, reads metadata from some files which are specified as follows:

<configuration configurationfile=”config.xml”>

<fileset dir=”.” includes=”Book.hbm.xml”/>

</configuration>

This tells the task to read configuration and mapping data from files config.xml and Book.hbm. xmi respectively. These are the files we used earlier to develop hibernate application. Only use the following DOCTYPE for correct operation:

http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd

Since it gathers metamodel information from standard files, it is called standard configuration. Given a configuration file and XML mapping files this configuration is usually used to generate database schema and Java POJO and DAO source files, documentation files etc. In general, a standard configuration takes the following form:

<configuration

configurationfile=”hibernate.cfg.xml”

propertyfile=”hibernate.properties”

entityresolver=”EntityResolver classname”

namingstrategy=”NamingStrategy classname”

>

<fileset…>

</configuration>

In addition to standard configuration, Hibernate tools also support annotation and JDBC-based configurations. An annotation-based configuration is used to read the meta model from annotated class and is created using <annotationconfiguration> tag as follows:

<annotationconfiguration configurationfile=”config.xml />

The annotated class is specified in the config.xml as follows:

<mapping class=”Book”/>

Given an annotated class this can be used to create database schema, mapping file and DAO class, documentation files etc.

A JDBC-based configuration is used to perform reverse engineering of a database from a JDBC connection using <jdbcconfiguration> tag. Here is an example JDBC configuration:

<jdbcconfiguration configurationfile=?Tconfig.xml” />

It reads the connection properties from an XML configuration file and may be used to generate Java POJO and DAO source files, mapping files, documentation etc. A JDBC configuration takes all attributes of <configuration> tag together with the following additional attributes:

<jdbcconfiguration

packagename=”package.name”

revengfile=”hibernate.reveng.xml”

reversestrategy=”ReverseEngineeringStrategy classname”

detectmanytomany=”true|false”

detectoptmisticlock=”true|false”

>

</jdbcconfiguration>

4. Exporters

These are the tags which actually convert the Hibernate metamodel into various artifacts. The following section describes various exporters available in the Hibernate Tool distribution.

Schema Exporter

For standard or annotation configuration and given a metamodel, this exporter (<hbm2ddl>) generates SQL DDL statements, which can be stored in a file and/or exported to the database directly.

<MyTask destdir=”./dest”>

<configuration configurationfile=”config.xml”>

<fileset dir=”.” includes=”Book.hbm.xml”/>

</configuration>

<hbm2ddl export=”true” outputfilename=”out.sql”/>

</MyTask>

It is used with standard configuration and generates the following SQL DDL query and stores it in a file out.sqi:

create table tbl_book (

no integer not null auto_increment,

name varchar(255),

pr integer,

primary key (no)

);

The notation export=”true” instructs the exporter to fire this query to the database also. The result may be checked using the following SQL statements:

Annotation configuration may also be used to generate the same as follows:

<MyTask destdir=”./dest”>

<classpath><path location=”.” /></classpath>

<annotationconfiguration configurationfile=”config.xml” />

<hbm2ddl export=”true” outputfilename=nout.sqln/>

</MyTask>

An additional <classpath> tag is necessary in this situation. In general <hbm2ddl> takes the following form:

<hbm2ddl drop=”true|false” create=”true|false” export=”true|false”

update=”true|false” outputfilename=”filename.ddl” delimiter=”;”

format=”true|false” >

POJO Class Exporter

This exporter (<hbm2java/>) generates Java POJO source files from any type of configuration. It takes the following form:

<hbm2java jdk5=”true|false” ejb3=”true|false” />

The jdk5 attribute controls if the code is JDK 5 compatible and ejb3 controls if the code should contain annotations. Here is an example:

<MyTask destdir=”./dest”>

<configuration configurationfile=”config.xml”>

<fileset dir=”.” includes=”Book.hbm.xml”/>

</configuration>

<hbm2java/>

</MyTask>

When used, it generated a POJO class Book.java in the dest directory as follows:

// default package

// Generated Mar 1, 2014 5:19:24 AM by Hibernate Tools 3.2.1.GA /**

* Book generated by hbm2java */

public class Book implements java.io.Serializable {

private int id; private String title;

private int price;

public Book() {  }

public Book(String title, int price) {

this.title = title;

this.price = price;
}
public int getId() { return this.id; }
public void setId(int id) { this.id = id; }
public String getTitle() { return this.title; }
public void setTitle(String title) { this.title = title; }
public int getPrice() { return this.price; }
public void setPrice(int price) { this.price = price; }
}

The following example generates an annotated Java source file.

<hbm2java ejb3=”true” />

DAO Exporter

Hibernate tools also allows us to create DAO via <hbm2dao> exporter as follows:

<MyTask destdir=”./dest”>

<configuration configurationfile=”config.xml”>

<fileset dir=”.” includes=”Book.hbm.xml”/>

</configuration>

<hbm2dao/>

</MyTask>

When used, it generated a DAO class file BookHome.java for Book in the dest directory as follows:

// default package

// Generated Mar 1, 2014 5:19:24 AM by Hibernate Tools 3.2.1.GA

import java.util.List;

import javax.naming.InitialContext;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.hibernate.LockMode;

import org.hibernate.SessionFactory;

import org.hibernate.criterion.Example;

/**

    • Home object for domain model class Book.
    • @see .Book
    • @author Hibernate Tools */

public class BookHome {

private static final Log log = LogFactory.getLog(BookHome.class);

private final SessionFactory sessionFactory = getSessionFactory();

protected SessionFactory getSessionFactory() {

try {

return (SessionFactory) new InitialContext().lookup(”SessionFactory”);

} catch (Exception e) {

log.error(”Could not locate SessionFactory in JNDI”, e); 

throw new IllegalStateException(”Could not locate SessionFactory in JNDI”);

}

}

public void persist(Book transientInstance) { log.debug(”persisting Book instance”);

try {

sessionFactory.getCurrentSession().persist(transientInstance);

log.debug(”persist successful”);

} catch (RuntimeException re) {

log.error(”persist failed”, re);

throw re;

}

}

}

This DAO class can then be used to load, store Book objects to the database. However, this generated class BookHome.java does not use persistence methods such as persist() within a transaction boundary, which is required for correct function of these methods. Usually, a layer above the DAO is used to control the Transaction boundaries. This might be Container Managed Transaction (CMT) or a manually managed transaction boundary. We use the latter method and insert a constructor as follows:

public BookHome(SessionFactory sf) {this.sessionFactory = sf;}

We also change the declaration of sessionFactory as follows:

private final SessionFactory sessionFactory;

To test this DAO, we write a test class DAOTest.java as follows:

//DAOTest.java import org.hibernate.*; import org.hibernate.cfg.*; public class DAOTest {

public static void main(String[] args) {

Configuration cfg = new Configuration();

cfg.configure(”config.xml”);

cfg.addResource(”Book.hbm.xml”);

SessionFactory factory = cfg.buildSessionFactory();

BookHome dao = new BookHome(factory);

Transaction tx=factory.getCurrentSession().beginTransaction();

Book b = new Book(”Introduction to Hibernate”, 400); dao.persist(b);

tx.commit();

factory.getCurrentSession().close();

factory.close();

}

}

Don’t forget to add the following property in config.xml file:

<property name=”hibernate.current_session_context_class”>thread</property>

The BookHome.java needs a package org.apache.commons.logging which can be found in org. apache.commons-logging-1.0.4.jar file. Put all the necessary JAR files in a directory required under the current directory. Use the following command to compile source files:

javac -cp .\required\*;. Book.java BookHome.java DAOTest.java

Run the application as follows:

java -cp .\required\*;. DAOTest

Mapping File Exporter

This exporter is used to generate hibernate mapping files and is usually intended to use with

<annotationconfiguration> or <jdbcconfiguration>. Here is an example:

<jdbcconfiguration configurationfile=”config.xml” />

<hbm2hbmxml/>

It generates a set of mapping files one for each table in the database specified by config.xmi file.

<annotationconfiguration configurationfile=”config.xml” />

<hbm2hbmxml/>

This generates mapping files one for each <mapping ciass=”..”/> entry in config.xmi file.

Configuration File Exporter

The <hbm2cfgxmi> exporter generates XML configuration file with name hibernate.cfg.xmi.

<jdbcconfiguration configurationfile=”config.xml” />

<hbm2cfgxml ejb3=”false”/>

The resultant configuration file hibernate.cfg.xmi contains properties used in config.xmi and adds a few more and adds mapping entries for each mapped class. Depending on the value of optional (default is faise) attribute ejb3, the mapping entries take the form <mapping resource=”…”/>

(faise) or <mapping ciass = “..”/> (true).

Documentation Exporter

The <hbm2doc> generates HTML docu^aentation for Java Source files and database sche^aa. It takes the following form:

<hbm2doc>

HBM Query Exporter

The <query> exporter is used to execute HQL statements and optionally storing the result in a file. It takes the following form:

<query destfiie=”fiiename”>HQL statement</query>

The following JAR file is needed to work with query exporter:

antlr_2.7.6.jar

commons.collections-3.2.1.jar

javassist-3.10.0.GA.jar

javax.transaction.jar

The following example stores the title of the books having price less than 300 in a file out.txt.

<query destfiie=”out.txt”>seiect titie from Book where price &it; 300</query>

Multiple statement can be executed using nested <hqi> elements as

<query destfile=”filename”>

<hql>HQL statement1</hql>

<hql>HQL statement2</hql>

</query>

Here is an example:

<query destfile=”out.txt”>

<hql>select title from Book where price &lt; 300</hql>

<hql>select count(*) from Book where price &lt; 300</hql>

</query>

This first stores the titles of the books having price less than 300 and finally appends the number of such books. Note that currently <query> exporter only supports DDL statements.

5. Controlling Reverse Engineering

A JDBC configured Ant task reads database metadata and creates a Hibernate metamodel. During this reverse engineering, a default strategy is used to map SQL types to Java types, to determine class names etc. For example, an SQL type varchar is converted to Java String etc. However, this strategy may be customized by the user. This is done by providing the strategy as an XML file (usually

hibernate.reveng.xml) and specifying it as a value revengfile attribute of <jdbcconfiguration> tag as follows:

<jdbcconfiguration configurationfile=”config.xml”

revengfile=”hibernate.reveng.xml”/>

The following additional JAR files are needed to work with custom reverse engineering:

cglib-2.1_3.jar

asm-1.5.3.jar

A sample reverse engineering strategy file takes the following form:

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

<!DOCTYPE hibernate-reverse-engineering SYSTEM

”http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd” >

<hibernate-reverse-engineering>

</hibernate-reverse-engineering>

To control the reverse engineering process <hibernate-reverse-engineering> tag contains various tags which must match (schema-selection*, type-mapping?, table-filter*, table*).

Schema Selection

By default the reverse engineering reads all tables from all schemas. This is sometimes unnecessary and may slow down the process. The <schema-selection> tag is used to select only necessary schemas which in turn can speed-up the process significantly. It takes the following form:

<schema-selection match-schema=”schema” match-catalog=”catalog” match-table=”table” />

The following example instructs reverse engineer to process all tables from the schema test.

<schema-selection match-schema=”test” />

The following results in processing only table tbl_book from schema test:

<schema-selection match-schema=”test” match-table=”tbl book”/>

Type Mappings

The <type-mapping> tag specifies how the database types should be mapped to Hibernate types. It takes the following form:

<type-mapping>

<sql-type

jdbc-type=”a java.sql.Types”

length=”a numeric value”

precision=”a numeric value”

scale=”a numeric value”

not-null=”true|false”

hibernate-type=”a hibernate type name”

/>

</type-mapping>

Here is an example:

<type-mapping>

<sql-type jdbc-type=”VARCHAR” length=’1′ hibernate-type=’char’ />

</type-mapping>

This specifies that a JDBC type varchar with length 1 should be mapped to Hibernate type char instead of default type string. The following maps varchar with length 10 as char[].

<sql-type jdbc-type=”VARCHAR” length=’10’ hibernate-type=’char[]’ />

Table Filters

The <tabie-fiiter> tag is used to include or exclude specific tables based on the schema. It takes the following form:

<table-filter

match-catalog=”catalog_matching_rule”

match-schema=”schema_matching_rule”

match-name=”table_matching_rule”

exclude=”true|false”

package=”package.name”

/>

The following results in processing of only table tbi_book.

<table-filter match-name=”tbl_book” />

Table Configuration

The <tabie> tag enables us to explicitly specify how to reverse engineer a particular table. For example, we can specify class and property names corresponding to table and table columns, which identifier generator should be used for the primary key etc. It takes the following form:

<table catalog=”a catalog” schema=”a schema” name=”a table” class=”a class” >

<primary-key…/>

<column…/>

<foreign-key…/>

</table>

Here is an example:

<table schema=”test” name=”tbl_book” class=”Book” >

<column name=”no” property=”id”/>

<column name=”name” property=”title”/>

<column name=”pr” property=”price”/>

</table>

This tells that the name of the resultant class corresponding to table tbi_book should be Book and names of the properties corresponding to table columns no, name and pr should be id, titie and price respectively.

6. Controlling POJO Code Generation

Hibernate tools also support controlling certain aspects of custom POJO code generation using <meta> tag to be used in mapping file. The <meta> tag has different attributes that tells what information has to be placed in the resultant POJO code. Here is an example:

<hibernate-mapping default-access=”property”>

<class name=”Book” table=”tbl_book”>

<meta attribute=”class-description”>

Javadoc for the Book class

@author UKR </meta>

<meta attribute=nimplements”>Resource</meta>

<id name=”id” type=”int” column=”no”>

<meta attribute=”field-description”>Unique id</meta>

<generator class=”native”/>

</id>

<property name=”title” column=”name” type=”string”/>

<property name=”price” column=”pr” type=”int”>

<meta attribute=nfield-description”>The price of the book</meta>

<meta attribute=nscope-field”>protected</meta>

</property>

</class>

</hibernate-mapping>

When used, this generated the following class:

// default package

// Generated Mar 3, 2014 7:19:01 PM by Hibernate Tools 3.4.0.CR1

/**

* Javadoc for the Book class

* @author UKR

*

*/

public class Book implements Resource,java.io.Serializable {

/**

* Unique id */

private int id; private String title;

/**

* The price of the book */

protected int price; public Book() { }

public Book(String title, int price) {

this.title = title;

this.price = price;

}

/**

* Unique id */

public int getId() { return this.id; }

public void setId(int id) { this.id = id; }

public String getTitle() { return this.title; }

public void setTitle(String title) { this.title = title; }

/**

* The price of the book */

public int getPrice() { return this.price; }

public void setPrice(int price) { this.price = price;}

}

The result of <meta> tag has been shown with bold face. A short description of list of attributes of <meta> tag is shown in Table 23.3:

Source: Uttam Kumar Roy (2015), Advanced Java programming, Oxford University Press.

Leave a Reply

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