Module 01 - Hibernate Entity Mapping-upd
Module 01 - Hibernate Entity Mapping-upd
© 2014 Time2Master 1
Entity Class Mapping
Entity classes can be thought of as the distinct
business concepts in a domain driven design
We will start with the basic Java class
requirements for persisting entity classes
After which we will go into identity mapping,
mapping data types, and Hibernate access
We will provide both XML and annotation
mapping examples for each subject we cover
Person
+name
© 2014 Time2Master 2
Class Requirements
Hibernate requires that entity classes have:
A field that can be used as identifier
A default constructor
Getter and Setter Methods for all properties
© 2014 Time2Master 3
About Annotations
Most of the mapping annotations we will use
are part of the Java Persistence API (JPA)
@Entity(name="MY_PERSON") Person class with
public class Person { JPA Annotations
@Id
@Column(name="PERSON_ID")
private long id;
@Column(name="FULLNAME")
private String name;
...
© 2014 Time2Master 4
Hibernate Annotations
Additional Hibernate specific functionality can
be exposed using Hibernate annotations
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
...
public Person() {}
public Person(String name) { this.name = name; }
© 2014 Time2Master 7
Entity Class Mapping:
MAPPING IDENTITY
© 2014 Time2Master 8
Primary key
A primary key is
Unique
No duplicate values
Constant
Value never changes
Required
Value can never be null
© 2014 Time2Master 9
Mapping Primary Keys
Object / Relational mismatch
Hibernate requires you to specify the property
that will map to the primary key
Prefer surrogate keys
Natural keys often lead to a brittle schema
© 2014 Time2Master 10
Generating Identity
Generated identity values
Ensure identity uniqueness
Private setId() methods
Ensure identity immutability
@Entity
public class Person {
@Id
@GeneratedValue Id is generated
private long id;
private String name;
public Person() {}
public Person(String name) { this.name = name; }
© 2014 Time2Master 11
Generation Strategies
Hibernate JPA Description
native AUTO Selects the best strategy for your database
identity IDENTITY Use an identity column (MS SQL, MySQL, HSQL, …)
sequence SEQUENCE Use a sequence (Oracle, PostgreSQL, SAP DB, …)
- TABLE Uses a table to hold last generated values for PKs
hilo - Like table, uses efficient algorithm to generate values
seqhilo - Like regular hilo, but using a sequence
increment - Finds the current max value and increments by 1*
uuid.hex - Creates globally unique 128-bit UUIDs
guid - Uses MySQL and MS SQL server global uid generator
select - Have Hibernate select a value generated by a trigger
assigned (implicit) Specifies that the value is assigned by the application
© 2014 Time2Master 12
Specifying Identity Generation
@GeneratedValue
@Entity @Entity Defaults to
public class Person { Specify the generation strategy public class Person { ‘AUTO’
@Id @Id when not
@GeneratedValue(strategy=GenerationType.AUTO) @GeneratedValue
private long id; private long id;
specified
private String name; private String name;
<generator> tag
<hibernate-mapping>
<class name="identity.Person"> Always have to
<id name="id"> specify a strategy,
<generator class="native" /> cannot leave it off
</id>
<property name="name" />
</class>
</hibernate-mapping>
© 2014 Time2Master 13
Identity Column
Identity columns are columns that can
automatically generate the next unique id
@Entity
public class Person { JPA identity strategy
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
private String name;
<hibernate-mapping>
<class name="identity.Person">
<id name="id">
<generator class="identity" />
</id>
<property name="name" />
</class>
XML identity strategy
</hibernate-mapping>
<hibernate-mapping>
<class name="identity.Person">
<id name="id">
<generator class="sequence" />
</id> Both native and sequence
<property name="name" />
</class>
</hibernate-mapping>
© 2014 Time2Master 15
Sequences
By default Hibernate only uses a single
sequence called ‘hibernate-sequence’
You can specify additional custom sequences
© 2014 Time2Master 16
Using Custom Sequences
Create Custom Sequence
@Entity
@SequenceGenerator(name="personSeq", sequenceName="PERSON_SEQUENCE")
public class Person_annotated_sequence {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="personSeq")
private long id;
Use Custom Sequence
...
<hibernate-mapping>
<class name="identity.Person">
<id name="id" >
Use ‘sequence’ strategy
<generator class="sequence">
<param name="sequence">PERSON_SEQUENCE</param>
</generator>
</id> Specify the custom
<property name="name" /> sequence
</class>
</hibernate-mapping>
© 2014 Time2Master 17
Entity Class Mapping
© 2014 Time2Master 18
Data Types
So far we haven’t specified any data types
Hibernate automatically mapped to SQL types
...
© 2014 Time2Master 19
Specify Date Type
Sometimes you need to be specific
Should a java.util.Date be stored as date, as a time
or as a timestamp in the database?
@Entity
public class Person {
@Id
@GeneratedValue
private long id;
private String name; Birthday will be
@Temporal(TemporalType.DATE) stored as a Date
private Date birthday;
...
© 2014 Time2Master 21
All in One Example
@Entity
public class Person { Name will be stored as:
@Id FULLNAME VARCHAR(255) NOT NULL
@GeneratedValue
private long id;
@Column(name="FULLNAME", length=255, nullable=false)
private String name;
@Temporal(TemporalType.DATE) Birthday will be
private Date birthday; stored as a Date
@Lob
private String biography;
@Transient
private String temp;
Biography will be stored as CLOB
instead of VARCHAR
...
© 2014 Time2Master 22
Basic Hibernate XML Types
Hibernate Type Java Type SQL Type
byte byte or java.lang.Byte TINYINT
short short or java.lang.Short SMALLINT
integer int or java.lang.Integer INTEGER
long long or java.lang.Long BIGINT
float float or java.lang.Float FLOAT
double double or java.lang.Double DOUBLE
big_decimal java.math.BigDecimal NUMERIC
boolean boolean BIT
yes_no boolean CHAR(1) – ‘Y’ or ‘N’
true_false boolean CHAR(1) – ‘T’ or ‘F’
string java.lang.String VARCHAR
character char, java.lang.Character or CHAR(1)
java.lang.String
© 2014 Time2Master 23
Date Time & Large Values
Hibernate Type Java Type SQL Type
date java.util.Date or java.sql.Date DATE
time java.util.Date or java.sql.Time TIME
timestamp java.util.Date or java.sql.Timestamp TIMESTAMP
calendar java.util.Calendar TIMESTAMP
calendar_date java.util.Calendar DATE
© 2014 Time2Master 24
XML Type Example
Same class and properties as the
previous annotation example
public class Person {
private long id; Now without
private String name; annotations
private Date birthday;
private String biography;
private String temp;
...
© 2014 Time2Master 26
Property or Field Access
Hibernate can access objects in two ways
property access gets and sets object values
through getter /setter methods
field access gets and sets object values directly
from / to the fields
@Entity @Entity
public class Person { public class Person {
@Id private long id;
@GeneratedValue private String name;
private long id;
private String name; public Person() {}
public Person(String name) { this.name = name; }
...
JPA field access @Id
@GeneratedValue JPA property access
public long getId() { return id; }
private void setId(long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
© 2014 Time2Master 27
Specifying Access with Annotations
The JPA specification lets you set the Access Type
with the location of @Id
Placing @Id on a field specifies field access for the
entire object
All other mapping annotations should be on the fields
Placing @Id on a getter specifies property access for
the entire object
All other mapping annotations should be on the getters
© 2014 Time2Master 28
Access Example
@Entity
public class Person {
private long id;
private String name;
private Date birthday;
@Temporal(TemporalType.DATE)
public Date getBirthday() { return birthday; }
public void setBirthday(Date birthday) { this.birthday = birthday; }
}
© 2014 Time2Master 29
Setting Access with XML
Use the “default-access” attribute on the
<hibernate-mapping> tag to set the default
Use the “access” attribute on the <property>
tag to change access for individual fields
Sets the default access
for Person to field
<hibernate-mapping default-access="field">
<class name="model.Person">
<id name="id">
<generator class="native" />
</id>
<property name="name" access="property" /> Changes the access for the name
<property name="birthday" type="date" /> attribute to property
</class>
</hibernate-mapping>
Birthday will be accessed through
its field (as set by the default)
© 2014 Time2Master 30
Access / Encapsulation
Property access hides implementation details
Maintains OO Principle of Encapsulation
© 2014 Time2Master 31
Encapsulation Example XML
public class Person {
private long id;
Table: PERSON
3 field implementation
private String firstname; details are encapsulated
private String lastname;
Mapped to 2 column table
public Person() {}
public Person() {}
@Column
public String getName() { return firstname + " " + lastname; }
public void setName(String name) { /* see code prev slide */; }
@Transient firstname
@Transient and lastname
public String getFirstname() { return firstname; }
public void setFirstname(String firstname) { this.firstname = firstname; }
@Transient
public String getLastname() { return lastname; }
public void setLastname(String lastname) { this.lastname = lastname; }
}
© 2014 Time2Master 33
Entity Class Mapping
WRAPPING UP
© 2014 Time2Master 34
Mapping Tips
You can specify a package attribute on the
<hibernate-mapping> XML element
No longer need fully qualified class names
Useful when mapping associations
© 2014 Time2Master 35
Active Learning
What do the following annotations do:
@Temporal @Transient
© 2014 Time2Master 36
Module Summary
In this module we covered entity class
mapping including:
Mapping an entity classes to tables
Mapping properties to columns
Mapping Identity and setting Identity Generation
Mapping Data types
Property / Field Access
These are the tools you use to map any class
© 2014 Time2Master 37