Hibernate can’t persist Java objects without a mapping document for each
class that tells Hibernate how to store the information it finds in the objects. In this section, we’ll lay out
the full mapping document and all the elements available to you. Then, in we’ll show how to
map from real Java classes to your database.
The format of the mapping document is:
<?xml version=" 1.0" ?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd>
<hibernate-mapping>
</hibernate-mapping>
To give you a good handle on this document, we’ll run through all the available elements and how they
affect Hibernate when you’re mapping Java objects to a database. Some of these mappings are compli-cated,
such as relationships and collections. We’ll touch on the elements here so you have a good idea
how they work, and then we’ll devote chapters to more detailed discussions of the topic.
<hibernate-mapping> Element
The <hibernate-mapping> element is the root element for the mapping document. Its format is:
<hibernate-mapping
schema="name" [optional]
default-cascade="none I save-update" [optional - default none]
auto-import="true | false" [optional - default true]
package="name" [optional]
/>
This element has four available attributes:
❑package: Fully qualifies unqualified classes in the mapping document. As you’ll see later, the
<class> element includes a name attribute that relates to the name of the Java class being
mapped. You can choose to use the package attribute and fully qualify the Java class. For
example:
<hibernate-mapping package="com.company">
<class name="Account"/>
</hibernate-mapping>
In this example, we’re mapping the class com.company.Account. If we didn’t add the
package attribute to the element, the system would expect to map a class called Account.
❑schema: Like the package attribute, fully qualifies the table used in this particular mapping. If
you add the schema attribute, the supplied namespace is appended to the table. For example:
<hibernate-mapping schema="products">
<class table="CD"> </class>
</hibernate-mapping>
In this example, the fully qualified database/table is products.CD. The schema attribute is
optional.
❑default-cascade: Specifies how actions that are performed on a parent are cascaded to a child.
The parent/child relationship is created through one-to-one, many-to-many, or one-to-many
mappings. (We’ll discuss these mappings in detail in Chapter 5.) For each mapping, you can
specify a cascade attribute; if you don’t, the default-cascade attribute’s value is used.
There are four possible values for default-cascade: all, none, save-update, and
delete. (The meanings are self-explanatory.) If you don’t specify a default-cascade
attribute, the default is none (no cascading of options occurs).
❑auto-import: If set to false, doesn’t allow unqualified class names in query strings. When you
build queries using HQL, you specify the class name provided in the <class name= ""> ele-ment.
The default is true; this attribute is optional.
<class> Element
Since we’re building a mapping file between a class and a database table, we need to specify the class
this mapping document references. The <class> element is designed for this purpose:
<class
name="name"
table="table" discriminator-value="value" [optional]
mutable="true | false" [optional - defaults to true]
schema="name" [optional]
proxy="interface" [optional]
dynamic-update="true | false" [optional - defaults false]
dynamic-insert="true | false" [optional - defaults false]
select-before-update="true | false" [optional - defaults false]
polymorphism="implicit | explicit" [optional - defaults implicit]
where="string" [optional]
persister="class" [optional]
batch-size="#" [optional -defaults 1]
optimistic-lock=""none | version | dirty | all"
[optional - defaults version]
lazy="true | false" [optional]
/>
The element includes 15 attributes:
❑name: Specifies the name of the Java class this mapping document is designed to represent.
Hibernate expects a fully qualified class name in this attribute if you don’t include the package
attribute in the <hibernate-mapping> element.
❑table: Specifies the name of the table to be used when persisting the Java object for this map-ping.
❑discriminator-value: Distinguishes between different classes in an inheritance hierarchy. The
default is the class name.
❑mutable: Signals whether an object persisted by Hibernate can be updated/deleted. If this
attribute is set to false, then the object is essentially read-only. The object can be persisted by
Hibernate but never updated or deleted from permanent storage.
❑schema: Overrides the value for the schema attribute specified in the <hibernate-mapping>
root element (if such a value has been set).
❑proxy: Tells Hibernate whether to use lazy initialization for objects of this mapping type. Lazy
initialization lets Hibernate stub out the data in an object. If you’re using lazy initialization, you
create objects and load them just in the example application in Chapter 3; but Hibernate won’t
populate (make a call to the database for data) until the object is used. The proxy attribute
requires that you provide a class to be used for the lazy initialization; this should normally be
the class name used in the name attribute.
❑dynamic-update: If true, then when Hibernate updates a row in the database for a class
attribute that has changed, it generates an UPDATE SQL statement at runtime during the
update() method call on the session and only include the columns of the table that have been
updated. This is an optional attribute; the default is false.
❑dynamic-insert: The same as dynamic-update in principle; but Hibernate dynamically creates
an INSERT SQL statement with only those columns that aren’t null values. This is an optional
attribute; the default is false.
❑select-before-update: If true, Hibernate performs a select to determine if an update is needed
(by default, Hibernate won’t perform an update unless the object has been modified). This is an
optional attribute; the default is false.
❑polymorphism: Specifies whether to use implicit or explicit polymorphism. As you’ll see later
in this chapter and in Chapter 6, you can define mappings that specify a hierarchy of objects
based on inheritance between Java classes. When a query, usually a find(), is executed,
Hibernate returns instances of this class when the class name or superclass is named in the
query; this is implicit polymorphism. In explicit polymorphism, Hibernate returns instances of
the class and its mapped subclasses. This attribute is optional; the default is implicit.
❑where: Specifies a global where clause for this class mapping.
persister: Specifies the class that will be used to persist this particular class to the database.
❑batch-size: Specifies the total number of instances to pull when Hibernate pulls instances from
the database for this class. This attribute is optional; the default is 1.
❑optimistic-lock: Specifies the type of locking used for the row, table, or database when updates
need to occur in the database. The values available are:
❑none: No optimistic locking.
❑version: Checks the version or timestamp column.
❑dirty: Checks those columns that have been changed.
❑all: Checks all columns.
This attribute is optional; the default is version.
❑lazy: If true, assumes the proxy attribute is included and the proxy class name is the same as the
mapped class name.
<id> Element
When you’re mapping a Java class to a database table, an ID is required. The ID is the primary key col-umn
of the database table used to persist a specific Java object. In addition, you should define a
setter/getter pair of methods, with the Java class for the ID following the JavaBean style. The <id> ele-ment
specifies information about the ID column. The format of the <id> element is as follows:
<id
name="name" [optional]
type="type" [optional]
column="column" [optional - defaults to name value]
unsaved-value="ant | none | null | value" [optional - defaults to null]
access="field | property | class" [optional - defaults to property]
<generator/>
/>
<generator class="class"
<param/>
/>
The <id> element has five elements and one subelement:
❑name: Specifies the name of the ID. This is an optional attribute; it’s included in many map-pings
with a value of "id".
❑type: Specifies the Hibernate type for the ID. If a type isn’t provided, Hibernate uses reflection
to try to determine the type. For a list of the Hibernate types, see the later description of the
<property> element.
❑column: Specifies the name of the database column. This is an optional attribute; if it isn’t speci-fied,
the database column name is the value in the name attribute. You need to include either the
name or the column attribute in the <id> element.
unsaved-value: Determines whether a newly instantiated object needs to be persisted (as men-tioned
in Chapter 3). This is an optional attribute; the default is null.
❑access: Specifies the way Hibernate accesses an object’s attribute using traditional JavaBean
style setter/getter methods. The values available for the access attribute are field, property,
or a class name. If you want Hibernate to use reflection and access the Java object’s attribute
directly, use the value "field". To build your own class for accessing the attribute of an object,
use as a value a class that implements net.sf.hibernate.property.PropertyAccessor.
❑<generator> subelement: Defined in the following section, “<generator> Element.”
<generator> Element
When Hibernate needs to add a new row to the database for a Java object that has been instantiated, it
must fill the ID column with a unique value in order to uniquely identify this persisted object. The
<generator> subelement of <id> specifies how the unique identifier should be created. The element
contains a single attribute called class, which specifies the class used to generate the ID. If parameters
are passed to the class, you use the <param name= "">value</param> element. Hibernate includes
a number of built-in generators that we’ll discuss next.
Increment
The increment generator is probably the most familiar creator of IDs. Each time the generator needs to
generate an ID, it performs a select on the current database, determines the current largest ID value, and
increment to the next value. Note that if you’re in a multithreaded environment this generator isn’t safe,
because two or more threads could obtain the same ID value and cause an exception on the database
server.
This generator supports all databases. It has no parameters. The possible column types are short, int, and
long. Here’s some example output:
+--------+------------+----------------------+---------------------+------+
| ID | title | artist | purchasedate | cost |
+--------+------------+----------------------+---------------------+------+
| 1 | Rush | Grace Under Pressure | 2004-04-03 00:00:00 | 9.99 |
| 2 | Nickelback | The Long Road | 2004-04-03 00:00:00 | 11.5 |
+--------+------------+----------------------+---------------------+------+
2 rows in set (0.23 sec)
Identity
If the database has an identity column associated with it, Hibernate can take advantage of the column to
indicate when an object hasn’t been added to the database. Supported databases include DB2, MySQL,
Microsoft SQL Server, Sybase, and HypersonicSQL. Be sure you use this generator with the correct
database. It has no parameters. The possible column types are short, int, and long.
Sequence
If the database has a sequence column associated with it, Hibernate can take advantage of the column to
determine if the object has been added to the database. Supported databases include DB2, PostgreSQL,
Oracle, SAP DB, McKoi, and InterBase. Be sure you use this generator with the correct database. It has
no parameters. The possible column types are short, int, and long.
Hilo
The hilo generator generates unique IDs for a database table. The IDs won’t necessarily be sequential.
This generator must have access to a secondary table that Hibernate uses to determine a seed value for
the generator. The default table is hibernate-unique-key, and the required column is next-value.
You need to insert one row in the table, as you saw in Chapter 3. Here’s a possible table-creation query:
create table hibernate-unique-key next-value int
);
insert into hibernate-unique-key values(100);
The hilo generator must be used with a Hibernate-generated connection. It shouldn’t be used with JTA
connections, according to the Hibernate reference manual.
You can provide three parameters to this generator to change the table name, column name, and maxi-mum
low value. For example:
<generator class="hilo">
<param name="table">hilo</param>
<param name="column">next</param>
<param name="max to">500</param>
</generator>
The possible column types are short, int, and long. Here’s some example output:
mysql> select * from cd;
+--------+------------+----------------------+---------------------+------+
| ID | title | artist | purchasedate | cost |
+--------+------------+----------------------+---------------------+------+
| 131073 | Rush | Grace Under Pressure | 2004-04-03 00:00:00 | 9.99 |
| 163841 | Nickelback | The Long Road | 2004-04-03 00:00:00 | 11.5 |
+--------+------------+----------------------+---------------------+------+
2 rows in set (0.23 sec)
seqhilo
With the seqhilo generator, Hibernate combines the sequence and hilo generators. Supported databases
include DB2, PostgreSQL, Oracle, SAP DB, McKoi, and InterBase. Be sure you use this generator with
the correct database.
You can provide a sequence name with a value of hi_value or low_value depending on the sequence
start. You can also provide a max_lo name with the starting value of the sequence. The possible column
types are short, int, and long.
Uuid.hex
This generator creates a unique strings based on appending the following values: the machine’s IP
address, the startup time of the current JVM, the current time, and the counter value. It supports all
databases and has no parameters. The possible column types are string, varchar, and text. Here’s some
example output:
mysql> select * from cd;
+-------------------+-------+---------------------+---------------------+----+
| ID | title | artist | purchasedate |cost|
+-------------------+-------+---------------------+---------------------+----+
| 40288195fbd50bb...| Rush | Grace Under Pressure| 2004-04-10 00:00:00 |9.99|
+-------------------+-------+---------------------+---------------------+----+
1 row in set (0.00 sec)
Uuid.string
This generator is like Uuid.hex, but the result is a string 16 characters long. It supports all databases except
PostgreSQL, and it has no parameters. Possible column types are string, varchar, and text. In the following
example output, the Marcus Roberts CD is using uuid.string:
mysql> select * from cd;
+--------------+--------------+---------------------+-------------------+-----+
| ID | title | artist | purchasedate |cost |
+--------------+--------------+---------------------+-------------------+-----+
| 40288195f... | Rush |Grace Under Pressure|2004-04-10 00:00:00 |9.99 |
| _¿_§{U?_?... |Marcus Roberts|the truth is spoken |2004-04-10 00:00:00 |13.88|
+--------------+--------------+---------------------+-------------------+-----+
2 rows in set (0.00 sec)
Native
The native generator picks identity, sequence, or hilo, depending on the database.
Assigned
If you need to assign the identifier yourself in your application, then use the assigned generator. You set
the identifier using the set<identifier> method of the Java class. The application assumes the
responsibility of making sure the id value is unique; otherwise, you’ll probably get a database insert
exception.
This generator supports all databases. Some level of application validation may need to occur. It has no
parameters. The column types are application dependent.
Foreign
When a class is part of a one-to-one relationship, it can be helpful to have a common ID between the objects.
By specifying the foreign generator, you make the class use the ID of the other class. This generator sup-ports
all databases and has no parameters.
<composite-id> Element
You can use Hibernate in many different coding situations, including accessing legacy databases. One of
the situations you’ll encounter when using a legacy database is a composite ID. A composite ID is made
up of numerous individual values to form a whole. Hibernate can handle the composite ID using the
<composite-id> element. (Chapter 5 includes a complete example that uses this element.)
The format of the <composite-id> is as follows:
<composite-id
[name=-string"]
[class="string"]
[unsaved-value=" [any] [none]"]
access=" [field] [property] [component class name]"
<key-property/>
<key-many-to-one/>
</composite-id>
There are two versions of <composite-id>. The first doesn’t include the name, class, and unsaved-value,
but uses the <key-property> and <key-many-to-one> elements to map the ID.
For example:
<composite-id>
<key-property name="ss"/>
<key-property name="account"/>
</composite-id>
In another situation, we’ll use a component class to represent the composite ID (as demonstrated in
Chapter 5).
The element’s attributes are as follows:
❑name: Attribute in the component class for the identifier class; the component class for the com-posite
ID.
❑unsaved-value: Default value for the attribute specifying whether the newly instantiated object
should be persisted to the database.
❑access: Possible values: field, property, or a class name. Hibernate accesses an object’s
attribute using traditional JavaBean style setter/getter methods. This form of access is specified
using the property value for the access attribute. If you want Hibernate to use reflection and
access the Java object’s attribute directly, use the value "field". If you want to build your own
class to access the attribute of an object, use as a value a class that implements net.sf.hiber-nate.
property.PropertyAccessor.
<discriminator> Element
If you’re mapping a hierarchy of objects with Hibernate, you have the option of using a mapping of a
table-per-class-hierarchy scheme, as we discussed in Chapter 1. For the single table to work
properly, a column is used to distinguish one class from another in the hierarchy. The <discrimina-tor>
element identifies the column in the table. The format of the element is:
<discriminator
column="column" [optional - defaults to class]
type="type" [optional - defaults to string]
force="true | false" [optional - defaults to false]
The element has three attributes:
❑column: Specifies the name of the column in the table to use as the discriminator column. This
attribute is optional; the default is class.
❑type: Specifies the type of the discriminator column. The default is string if the attribute isn’t
included. The valid types are string, character, integer, byte, short, Boolean, yes no, and true
false. Some of these types will only handle two different classes.
❑force: Determines whether Hibernate uses discriminator values when retrieving all instances of
a root class. This attribute is optional; the default is false.
Notice that the element doesn’t specify the value to place in the column. The value is determined with
the discriminator-value attribute, which we discuss in the sections on the <class> element and
the <subclass> element.
<version> Element
If data in your object needs to be versioned as opposed to having a unique ID, you can use the <ver-sion>
or <timestamp> (discussed next) element to keep the data up to date. There is no generator for
the version or timestamp. The application must handle populating the Java class attribute with the
correct value. You’ll see an example of using a version/timestamp column in Chapter 5.
The format of the element is
<version
column="column" [optional - defaults to name value]
name=”name"
type="type" [optional - defaults to integer]
access="field | property | class" [optional - defaults to property]
unsaved-value="null | negative | undefined"
[optional - defaults to undefined]
/>
The <version> element has five attributes:
❑column: Specifies the name of the column to use for the identifier. This attribute is optional; the
default is the value of the name attribute.
❑name: Specifies the name of the Java class’s version attribute.
❑type: Specifies the type of the version attribute. This attribute is optional; the default is int.
❑access: See the description in our discussion of the <id> element.
❑unsaved-value: Indicates whether the object is newly instantiated. Hibernate uses the value to
determine whether the object needs to be persisted. This is an optional attribute; the default is
undefined.
<timestamp> Element
The <timestamp> element is used in much the same manner as the <version> element. It has five
attributes:
❑column: Specifies the name of the column to use for the identifier. This attribute is optional; the
default is the value of the name attribute.
❑name: Specifies the name of the Java class’s timestamp attribute.
❑type: Specifies the type of the timestamp attribute. This attribute is optional; the default is
int.
❑access: See the description in our discussion of the <id> element.
❑unsaved-value: Indicates whether the object is newly instantiated. Hibernate uses the value to
determine whether the object needs to be persisted. This is an optional attribute; the default is
undefined.
<property> Element
For each of the attributes in your Java class that should be saved to the database when an object is per-sisted,
you need to define a <property> element in the mapping document. The persisted attributes
must be JavaBean compliant. The format of the element is as follows:
<property
name="name"
column="column" [optional - defaults to name value]
type="type" [optional]
update="true | false" [optional - defaults to true]
insert="true | false" [optional - defaults to true]
formula="sql string" [optional]
access="field | property | class" [optional - defaults to property]
/>
The <property> element has seven possible attributes:
❑name: Specifies the name of the property. Note that the first character of the name must
be lowercase.
❑column: Specifies the name of the column in the database table where this attribute should be
saved. This is an optional attribute; Hibernate uses a column name equal to the value of the
name attribute if it’s missing.
❑type: Specifies the name of the Hibernate type for this mapped Java attribute. If the type isn’t
specified, Hibernate attempts to determine the type using reflection. The reflection process isn’t
as easy as you’d expect, but it’s based on a set of rules. The Hibernate types available as well as
the rules are as follows:
❑First attempt: to reflect to a basic type: