Toolset Guide
Roundtrip engineering with Hibernate is possible using a set of commandline tools
maintained as part of the Hibernate project, along with Hibernate support built into
XDoclet, Middlegen and AndroMDA.
The Hibernate main package comes bundled with the most important tool (it can even
be used from "inside" Hibernate on-the-fly):
DDL schema generation from a mapping file
(aka SchemaExport, hbm2ddl)
Other tools directly provided by the Hibernate project are delivered with a separate
package, Hibernate Extensions. This package includes tools for
the following tasks:
Java source generation from a mapping file (aka CodeGenerator,
hbm2java)
mapping file generation from compiled Java classes or from
Java source with XDoclet markup (aka MapGenerator,
class2hbm)
There's actually another utitily living in Hibernate Extensions: ddl2hbm.
It is considered deprecated and will no longer be maintained, Middlegen does a better job
for the same task.
Third party tools with Hibernate support are:
Middlegen (mapping file generation from an existing database schema)
AndroMDA (MDA (Model-Driven Architecture) approach generating code for
persistent classes from UML diagrams and their XML/XMI representation)
These 3rd party tools are not documented in this reference. Please refer to the Hibernate
website for up-to-date information (a snapshot of the site is included in the Hibernate
main package).
Schema Generation
DDL may be generated from your mapping files by a command line utility. A batch file
is located in the hibernate-x.x.x/bin directory of the core
Hibernate package.
The generated schema include referential integrity constraints (primary and foreign keys) for entity
and collection tables. Tables and sequences are also created for mapped identifier generators.
You must specify a SQL Dialect via the
hibernate.dialect property when using this tool.
Customizing the schema
Many Hibernate mapping elements define an optional attribute named length. You may set
the length of a column with this attribute. (Or, for numeric/decimal data types, the precision.)
Some tags also accept a not-null attribute (for generating a NOT NULL
constraint on table columns) and a unique attribute (for generating UNIQUE
constraint on table columns).
Some tags accept an index attribute for specifying the
name of an index for that column. A unique-key attribute
can be used to group columns in a single unit key constraint. Currently, the
specified value of the unique-key attribute is
not used to name the constraint, only to group the
columns in the mapping file.
Examples:
]]>
Alternatively, these elements also accept a child <column> element. This is
particularly useful for multi-column types:
]]>
The sql-type attribute allows the user to override the default mapping
of Hibernate type to SQL datatype.
The check attribute allows you to specify a check constraint.
...
]]>
Summary
Attribute
Values
Interpretation
length
number
column length/decimal precision
not-null
true|false
specfies that the column should be non-nullable
unique
true|false
specifies that the column should have a unique constraint
index
index_name
specifies the name of a (multi-column) index
unique-key
unique_key_name
specifies the name of a multi-column unique constraint
foreign-key
foreign_key_name
specifies the name of the foreign key constraint generated
for an association
sql-type
column_type
overrides the default column type (attribute of
<column> element only)
check
SQL expression
create an SQL check constraint on either column or table
Running the tool
The SchemaExport tool writes a DDL script to standard out and/or
executes the DDL statements.
java -cp hibernate_classpaths
net.sf.hibernate.tool.hbm2ddl.SchemaExport options mapping_files
SchemaExport Command Line Options
Option
Description
--quiet
don't output the script to stdout
--drop
only drop the tables
--text
don't export to the database
--output=my_schema.ddl
output the ddl script to a file
--config=hibernate.cfg.xml
read Hibernate configuration from an XML file
--properties=hibernate.properties
read database properties from a file
--format
format the generated SQL nicely in the script
--delimiter=x
set an end of line delimiter for the script
You may even embed SchemaExport in your application:
Properties
Database properties may be specified
as system properties with -D<property>
in hibernate.properties
in a named properties file with --properties
The needed properties are:
SchemaExport Connection Properties
Property Name
Description
hibernate.connection.driver_class
jdbc driver class
hibernate.connection.url
jdbc url
hibernate.connection.username
database user
hibernate.connection.password
user password
hibernate.dialect
dialect
Using Ant
You can call SchemaExport from your Ant build script:
]]>
Incremental schema updates
The SchemaUpdate tool will update an existing schema with "incremental" changes.
Note that SchemaUpdate depends heavily upon the JDBC metadata API, so it will
not work with all JDBC drivers.
java -cp hibernate_classpaths
net.sf.hibernate.tool.hbm2ddl.SchemaUpdate options mapping_files
SchemaUpdate Command Line Options
Option
Description
--quiet
don't output the script to stdout
--properties=hibernate.properties
read database properties from a file
You may embed SchemaUpdate in your application:
Using Ant for incremental schema updates
You can call SchemaUpdate from the Ant script:
]]>
Code Generation
The Hibernate code generator may be used to generate skeletal Java implementation classes
from a Hibernate mapping file. This tool is included in the Hibernate Extensions package
(a seperate download).
hbm2java parses the mapping files and generates fully working Java
source files from these. Thus with hbm2java one could "just" provide the
.hbm files, and then don't worry about hand-writing/coding the Java files.
java -cp hibernate_classpaths
net.sf.hibernate.tool.hbm2java.CodeGenerator options
mapping_files
Code Generator Command Line Options
Option
Description
--output=output_dir
root directory for generated code
--config=config_file
optional file for configuring hbm2java
The config file (optional)
The config file provides for a way to specify multiple "renderers" for the source code
and to declare <meta> attributes that is "global" in scope. See
more about this in the <meta> attribute section.
codegen.test.IAuditable
]]>
This config file declares a global meta attribute "implements" and specify two renderers, the
default one (BasicRenderer) and a renderer that generates Finder's (See more in "Basic Finder
generation" below).
The second renderer is provided with a package and suffix attribute.
The package attribute specifies that the generated source files from this renderer should be
placed here instead of the package scope specified in the .hbm files.
The suffix attribute specifies the suffix for generated files. E.g. here a file named
Foo.java would be FooFinder.java instead.
It is also possible to send down arbitrary parameters to the renders by adding <param> attributes
to the <generate> elements.
hbm2java currently has support for one such parameter,
namely
generate-concrete-empty-classes which
informs the BasicRenderer to only generate empty
concrete classes that extends a base class for all your
classes. The following config.xml example illustrate
this feature
true
Base
]]>
Notice that this config.xml configure 2 (two)
renderers. One that generates the Base classes, and a
second one that just generates empty concrete classes.
The meta attribute
The <meta> tag is a simple way of annotating the hbm.xml
with information, so tools have a natural place to store/read information that is not directly related
to the Hibernate core.
You can use the <meta> tag to tell hbm2java to only
generate "protected" setters, have classes always implement a certain set of interfaces or
even have them extend a certain base class and even more.
The following example:
Javadoc for the Person class
@author Frodo
IAuditable
protected
The name of the person
]]>
will produce something like the following (code shortened for better understanding). Notice the
Javadoc comment and the protected set methods:
Supported meta tags
Attribute
Description
class-description
inserted into the javadoc for classes
field-description
inserted into the javadoc for fields/properties
interface
If true an interface is generated instead of an class.
implements
interface the class should implement
extends
class the class should extend (ignored for subclasses)
generated-class
overrule the name of the actual class generated
scope-class
scope for class
scope-set
scope for setter method
scope-get
scope for getter method
scope-field
scope for actual field
use-in-tostring
include this property in the toString()
implement-equals
include a equals() and hashCode() method in this class.
use-in-equals
include this property in the equals() and hashCode() method.
bound
add propertyChangeListener support for a property
constrained
bound + vetoChangeListener support for a property
gen-property
property will not be generated if false (use with care)
property-type
Overrides the default type of property. Use this with any tag's to specify the concrete type instead of just Object.
class-code
Extra code that will inserted at the end of the class
extra-import
Extra import that will inserted at the end of all other imports
finder-method
see "Basic finder generator" below
session-method
see "Basic finder generator" below
Attributes declared via the <meta> tag are per default
"inherited" inside an hbm.xml file.
What does that mean? It means that if you e.g want to have all your classes
implement IAuditable then you just add an
<meta attribute="implements">IAuditable</meta> in the top of
the hbm.xml file, just after
<hibernate-mapping>. Now all classes defined in that
hbm.xml file will implement IAuditable!
(Except if a class also has an "implements" meta attribute, because local specified
meta tags always overrules/replaces any inherited meta tags).
Note: This applies to all <meta>-tags.
Thus it can also e.g. be used to specify that all fields should be declare protected,
instead of the default private. This is done by adding <meta
attribute="scope-field">protected</meta> at e.g. just under the
<class> tag and all fields of that class will be protected.
To avoid having a <meta>-tag inherited then you can simply
specify inherit="false" for the attribute, e.g.
<meta attribute="scope-class" inherit="false">public abstract</meta>
will restrict the "class-scope" to the current class, not the subclasses.
Basic finder generator
It is now possible to have hbm2java generate basic finders for
Hibernate properties. This requires two things in the hbm.xml
files.
The first is an indication of which fields you want to generate finders for. You indicate
that with a meta block inside a property tag such as:
findByName
]]>
The finder method name will be the text enclosed in the meta tags.
The second is to create a config file for hbm2java of the format:
]]>
And then use the param to hbm2java --config=xxx.xml where
xxx.xml is the config file you just created.
An optional parameter is meta tag at the class level of the format:
com.whatever.SessionTable.getSessionTable().getSession();
]]>
Which would be the way in which you get sessions if you use the
Thread Local Session pattern (documented in the Design Patterns
area of the Hibernate website).
Velocity based renderer/generator
It is now possible to use velocity as an alternative rendering mechanism.
The follwing config.xml shows how to configure hbm2java to use its velocity renderer.
pojo.vm
]]>
The parameter named template is a resource path to the velocity macro file you want to use.
This file must be available via the classpath for hbm2java. Thus remember to add the directory where pojo.vm
is located to your ant task or shell script. (The default location is ./tools/src/velocity)
Be aware that the current pojo.vm generates only the most basic parts of the java beans.
It is not as complete and feature rich as the default renderer - primarily a lot of the meta tags
are not supported.
Mapping File Generation
A skeletal mapping file may be generated from compiled persistent classes using
a command line utility called MapGenerator. This utility is part of
the Hibernate Extensions package.
The Hibernate mapping generator provides a mechanism to produce mappings from
compiled classes. It uses Java reflection to find properties
and uses heuristics to guess an appropriate mapping from the property type.
The generated mapping is intended to be a starting point only. There is no way to produce
a full Hibernate mapping without extra input from the user. However, the tool does
take away some of the repetitive "grunt" work involved in producing a mapping.
Classes are added to the mapping one at a time. The tool will reject
classes that it judges are are not Hibernate persistable.
To be Hibernate persistable a class
must not be a primitive type
must not be an array
must not be an interface
must not be a nested class
must have a default (zero argument) constructor.
Note that interfaces and nested classes actually are persistable by Hibernate, but
this would not usually be intended by the user.
MapGenerator will climb the superclass chain of all added classes attempting
to add as many Hibernate persistable superclasses as possible to the same database table.
The search stops as soon as a property is found that has a name appearing on a list of
candidate UID names.
The default list of candidate UID property names is: uid, UID,
id, ID, key, KEY,
pk, PK.
Properties are discovered when there are two methods in the class, a setter and a getter, where the
type of the setter's single argument is the same as the return type of the zero argument getter,
and the setter returns void. Furthermore, the setter's name must start with the
string set and either the getter's name starts with get or
the getter's name starts with is and the type of the property is boolean. In
either case, the remainder of their names must match. This matching portion is the name of
the property, except that the initial character of the property name is made lower case if
the second letter is lower case.
The rules for determining the database type of each property are as follows:
If the Java type is Hibernate.basic(), then the property is a
simple column of that type.
For hibernate.type.Type custom types and PersistentEnum
a simple column is used as well.
If the property type is an array, then a Hibernate array is used, and MapGenerator
attempts to reflect on the array element type.
If the property has type java.util.List, java.util.Map, or
java.util.Set, then the corresponding Hibernate types are used, but
MapGenerator cannot further process the insides of these types.
If the property's type is any other class, MapGenerator defers the decision
on the database representation until all classes have been processed. At this point, if the
class was discovered through the superclass search described above, then the property is
an many-to-one association. If the class has any properties, then it is
a component. Otherwise it is serializable, or not persistable.
Running the tool
The tool writes XML mappings to standard out and/or to a file.
When invoking the tool you must place your compiled classes on the classpath.
java -cp hibernate_and_your_class_classpaths
net.sf.hibernate.tool.class2hbm.MapGenerator options and
classnames
There are two modes of operation: command line or interactive.
The interactive mode is selected by providing the single command line argument
--interact. This mode provides a prompt response console. Using it you
can set the UID property name for each class using the uid=XXX command
where XXX is the UID property name. Other command alternatives are simply
a fully qualified class name, or the command done which emits the XML and terminates.
In command line mode the arguments are the options below interspersed with fully qualified
class names of the classes to be processed. Most of the options are meant to be used
multiple times; each use affects subsequently added classes.
MapGenerator Command Line Options
Option
Description
--quiet
don't output the O-R Mapping to stdout
--setUID=uid
set the list of candidate UIDs to the singleton uid
--addUID=uid
add uid to the front of the list of candidate UIDs
--select=mode
mode use select mode mode(e.g.,
distinct or all) for subsequently
added classes
--depth=<small-int>
limit the depth of component data recursion for subsequently added classes
--output=my_mapping.xml
output the O-R Mapping to a file
full.class.Name
add the class to the mapping
--abstract=full.class.Name
see below
The abstract switch directs the map generator tool to ignore specific super classes so
that classes with common inheritance are not mapped to one large table. For instance,
consider these class hierarchies:
Animal-->Mammal-->Human
Animal-->Mammal-->Marsupial-->Kangaroo
If the --abstractswitch is not used, all classes will
be mapped as subclasses of Animal, resulting in one large table containing
all the properties of all the classes plus a discriminator column to indicate which subclass is
actually stored. If Mammal is marked as abstract,
Human and Marsupial will be mapped to
separate <class> declarations and stored in separate tables.
Kangaroo will still be a subclass of Marsupial
unless Marsupial is also marked as abstract.