-
Language:
English
-
Language:
English
Red Hat Training
A Red Hat training course is available for Red Hat JBoss Web Server
5.2. Hibernate Types
5.2.1. Entities and Values
In relation to the persistence service, Java language-level objects are classified into two groups:
An entity exists independently of any other objects holding references to the entity. Contrast this with the usual Java model, where an unreferenced object is garbage collected. Entities must be explicitly saved and deleted. Saves and deletions, however, can be cascaded from a parent entity to its children. This is different from the ODMG model of object persistence by reachability and corresponds more closely to how application objects are usually used in large systems. Entities support circular and shared references. They can also be versioned.
An entity's persistent state consists of references to other entities and instances of value types. Values are primitives: collections (not what is inside a collection), components and certain immutable objects. Unlike entities, values in particular collections and components, are persisted and deleted by reachability. Since value objects and primitives are persisted and deleted along with their containing entity, they cannot be independently versioned. Values have no independent identity, so they cannot be shared by two entities or collections.
Until now, we have been using the term "persistent class" to refer to entities. We will continue to do that. Not all user-defined classes with a persistent state, however, are entities. A component is a user-defined class with value semantics. A Java property of type
java.lang.String
also has value semantics. Given this definition, all types (classes) provided by the JDK have value type semantics in Java, while user-defined types can be mapped with entity or value type semantics. This decision is up to the application developer. An entity class in a domain model will normally have shared references to a single instance of that class, while composition or aggregation usually translates to a value type.
We will revisit both concepts throughout this reference guide.
The challenge is to map the Java type system, and the developers' definition of entities and value types, to the SQL/database type system. The bridge between both systems is provided by Hibernate. For entities,
<class>
, <subclass>
and so on are used. For value types we use <property>
, <component>
etc., that usually have a type
attribute. The value of this attribute is the name of a Hibernate mapping type. Hibernate provides a range of mappings for standard JDK value types out of the box. You can write your own mapping types and implement your own custom conversion strategies.
With the exception of collections, all built-in Hibernate types support null semantics.
5.2.2. Basic Value Types
The built-in basic mapping types can be roughly categorized into the following:
integer, long, short, float, double, character, byte, boolean, yes_no, true_false
- Type mappings from Java primitives or wrapper classes to appropriate (vendor-specific) SQL column types.
boolean, yes_no
andtrue_false
are all alternative encodings for a Javaboolean
orjava.lang.Boolean
. string
- A type mapping from
java.lang.String
toVARCHAR
(or OracleVARCHAR2
). date, time, timestamp
- Type mappings from
java.util.Date
and its subclasses to SQL typesDATE
,TIME
andTIMESTAMP
(or equivalent). calendar, calendar_date
- Type mappings from
java.util.Calendar
to SQL typesTIMESTAMP
andDATE
(or equivalent). big_decimal, big_integer
- Type mappings from
java.math.BigDecimal
andjava.math.BigInteger
toNUMERIC
(or OracleNUMBER
). locale, timezone, currency
- Type mappings from
java.util.Locale
,java.util.TimeZone
andjava.util.Currency
toVARCHAR
(or OracleVARCHAR2
). Instances ofLocale
andCurrency
are mapped to their ISO codes. Instances ofTimeZone
are mapped to theirID
. class
- A type mapping from
java.lang.Class
toVARCHAR
(or OracleVARCHAR2
). AClass
is mapped to its fully qualified name. binary
- Maps byte arrays to an appropriate SQL binary type.
text
- Maps long Java strings to a SQL
CLOB
orTEXT
type. serializable
- Maps serializable Java types to an appropriate SQL binary type. You can also indicate the Hibernate type
serializable
with the name of a serializable Java class or interface that does not default to a basic type. clob, blob
- Type mappings for the JDBC classes
java.sql.Clob
andjava.sql.Blob
. These types can be inconvenient for some applications, since the blob or clob object cannot be reused outside of a transaction. Driver support is patchy and inconsistent. imm_date, imm_time, imm_timestamp, imm_calendar, imm_calendar_date, imm_serializable, imm_binary
- Type mappings for what are considered mutable Java types. This is where Hibernate makes certain optimizations appropriate only for immutable Java types, and the application treats the object as immutable. For example, you should not call
Date.setTime()
for an instance mapped asimm_timestamp
. To change the value of the property, and have that change made persistent, the application must assign a new, nonidentical, object to the property.
Unique identifiers of entities and collections can be of any basic type except
binary
, blob
and clob
. Composite identifiers are also allowed. See below for more information.
The basic value types have corresponding
Type
constants defined on org.hibernate.Hibernate
. For example, Hibernate.STRING
represents the string
type.
5.2.3. Custom Value Types
It is relatively easy for developers to create their own value types. For example, you might want to persist properties of type
java.lang.BigInteger
to VARCHAR
columns. Hibernate does not provide a built-in type for this. Custom types are not limited to mapping a property, or collection element, to a single table column. So, for example, you might have a Java property getName()
/setName()
of type java.lang.String
that is persisted to the columns FIRST_NAME
, INITIAL
, SURNAME
.
To implement a custom type, implement either
org.hibernate.UserType
or org.hibernate.CompositeUserType
and declare properties using the fully qualified classname of the type. View org.hibernate.test.DoubleStringType
to see the kind of things that are possible.
<property name="twoStrings" type="org.hibernate.test.DoubleStringType"> <column name="first_string"/> <column name="second_string"/> </property>
Notice the use of
<column>
tags to map a property to multiple columns.
The
CompositeUserType
, EnhancedUserType
, UserCollectionType
, and UserVersionType
interfaces provide support for more specialized uses.
You can even supply parameters to a
UserType
in the mapping file. To do this, your UserType
must implement the org.hibernate.usertype.ParameterizedType
interface. To supply parameters to your custom type, you can use the <type>
element in your mapping files.
<property name="priority"> <type name="com.mycompany.usertypes.DefaultValueIntegerType"> <param name="default">0</param> </type> </property>
The
UserType
can now retrieve the value for the parameter named default
from the Properties
object passed to it.
If you regularly use a certain
UserType
, it is useful to define a shorter name for it. You can do this using the <typedef>
element. Typedefs assign a name to a custom type, and can also contain a list of default parameter values if the type is parameterized.
<typedef class="com.mycompany.usertypes.DefaultValueIntegerType" name="default_zero"> <param name="default">0</param> </typedef>
<property name="priority" type="default_zero"/>
It is also possible to override the parameters supplied in a typedef on a case-by-case basis by using type parameters on the property mapping.
Even though Hibernate's rich range of built-in types and support for components means you will rarely need to use a custom type, it is considered good practice to use custom types for non-entity classes that occur frequently in your application. For example, a
MonetaryAmount
class is a good candidate for a CompositeUserType
, even though it could be mapped as a component. One reason for this is abstraction. With a custom type, your mapping documents would be protected against changes to the way monetary values are represented.