Sie sind auf Seite 1von 49

Overview of Hibernate -

II
Objectives
In this session, you will learn to:
Mapping value type objects
Mapping collection
Mapping database relationships
Mapping class Inheritance
Mapping Value Type Objects
While developing an application, you may find that a common property
is shared among different classes of the application.
Sometimes, shared property consists of multiple constituent elements.
For example, your application consists of two classes, Employee and
Student, and both these classes have a common property named
address.
To accomplish reusability and modularity in your application, you can:
Create a Java class to represent the shared property.
Refer the Java class from any class in the application.

This Java class is referred to as the value type.


The value types:
Are mapped as a component of the entity class.
Are mapped by using the <component> element in the Hibernate
mapping file.
Mapping Value Type Objects (Contd.)
Consider a scenario where you are developing an application that stores
information about the orders placed by different customers of an
organization in a database. For this, you have created the ORDERS table
by using the following query:
ORDERS table
CREATE TABLE ORDERS ( ORDER_ID INT PRIMARY KEY,
ONLINE_RECIPIENT VARCHAR(40), ONLINE_ADDRESS
VARCHAR(100), OFFLINE_RECIPIENT VARCHAR(40),
OFFLINE_ADDRESS VARCHAR(100))

To map the ORDERS table, a Java class named OrderDetails is created


by using the following code snippet:
OrderDetails class
public class OrderDetails{
private int orderID;
private String onlineRecipient;
private String onlineAddress;
private String offlineRecipient;
private String offlineAddress;
//getter and setter methods to set the properties
. . . . .
}
Mapping Value Type Objects (Contd.)
A solution to the preceding problem is to create a new class that
encapsulates the contact details of the customers.
A separate class, ContactDetails is created to encapsulate the
address of the customers, as shown in the following code snippet:

public class ContactDetails


{
private String recipient;
private String address;
// getter and setter methods
. . . . . .
}
Mapping Value Type Objects (Contd.)
Two different instances of the ContactDetails class for the online and
offline contact details can be created.
The OrderDetails class can use these instances to specify the online
and offline contact details, as shown in the following code snippet:
public class OrderDetails {
private int orderID;
private ContactDetails onlineContact;
private ContactDetails offlineContact;
// getter and setter methods
. . . . . . .
}

The contact details are dependent on the OrdersDetails class. This


implies that you cannot model the ContactDetails class as an
independent persistent class.
It needs to be associated as a component of an entity class that has a
database identity.
Therefore, the OrderDetails class is an entity class and the
ContactDetails class is modeled as its component.
Mapping Value Type Objects (Contd.)
In Hibernate applications, the mapping of a component class is different
from the mapping of an entity class.
The mapping of an entity class is configured under the <id> tag that is
used to create a unique identifier for its object. However, the component
class is configured under a <component> tag.
The following code snippet shows the mapping of the OrderDetails
and ContactDetails classes in the Hibernate mapping file:
<class name="OrderDetails" table="ORDER">
<id name="orderID" type="int" column="ORDER_ID">
<generator class="native" />
</id>
<component name="onlineContact" class="ContactDetails">
<property name="recipient" type="string" column="ONLINE_RECIPIENT" />
<property name="address" type="string" column="ONLINE_ADDRESS"/>
</component>
<component name="offlineContact" class="ContactDetails">
<property name="recipient" type="string" column="OFFLINE_RECIPIENT" />
<property name="address" type="string" column="OFFLINE_ADDRESS" />
</component>
. . . . . . . . . .
</class>
</hibernate-mapping>
Activity: Mapping Value Type Object
Consider a scenario where you need to create a Java application that
implement mapping of the value type object. Application should be
based on the following guideline.
Student table contains column , such as ID, name, and address however
member variable of an address column ,such as street, city, state, and pin
code are object instead of a simple data type.
Application should list following tasks as an option:
 1. for Insert
 2. for List
 3. for Update
 4. for Delete
Identifying Mapping of Collection
When a property of a class is declared as a collection, you need to
perform collection mapping in the Hibernate mapping file.
The commonly used collection mapping elements in the Hibernate
mapping file are:
<set>
<list>
<bag>
Identifying Mapping of Collection (Contd.)
The <set> element:
Is used when the duplicate elements are not required in the collection.
Does not maintain the order of its elements in the collection.
Is used to map an attribute of the java.util.Set collection type in the
Hibernate mapping file.
Uses the following sub elements and attributes to achieve mapping
between the application and the database tables:
 cascade attribute: Specifies that the operations performed on an entity update
the related entities also.
 name attribute: Specifies the name of the database table that stores the
collection objects
 <key> element: Specifies the properties that associate the entity and the
collection objects
 <one-to-many> element: Specifies a one-to-many relationship between the
entity and the collection objects. It contains the class attribute. This attribute
contains the name of the collection object.
Identifying Mapping of Collection (Contd.)
Consider a scenario, you are developing an application that stores the
details of authors and the books written by them. For this, you have
created the Authors class that contains the following code snippet:

import java.util.Set;
public class Authors public void setAuthorName(String
{ authorName) {
private String authorID; this.authorName =
private String authorName; authorName;
private Set<Books> books; }

public String getAuthorID() public Set<Books> getBooks()


{ {
return authorID; return books;
} }
public void public void
setAuthorID(String authorID) { setBooks(Set<Books> books) {
this.authorID = this.books = books;
authorID; }
} }
public String getAuthorName()
{
return authorName;
}
Identifying Mapping of Collection (Contd.)
In the preceding slide, the books property is a collection of instances of
the Books class. The Authors class is called an entity which owns the
collection of the Books class.
package Test;
public class Books {
private String bookID;
private String bookName;
public String getBookID() {
return bookID;
}
public void setBookID(String
bookID) {
this.bookID = bookID;
}
public String getBookName() {
return bookName;
}
public void setBookName(String
bookName) {
this.bookName = bookName;
}
}
Identifying Mapping of Collection (Contd.)
The collection objects are distinguished in the database by the foreign
key of the entity that owns the collection.
This foreign key is referred to as the collection key column. The collection
key column is mapped by the <key> element in the mapping file.
The following figure shows how the author and book details are stored in
the database.
Books

AUTHORS
BOOKID

AUTHORID
AUTHORID

AUTHORNAME
BOOKNAME
Identifying Mapping of Collection (Contd.)
You can map the Authors and Books class with the AUTHORS and
BOOKS tables in the Hibernate mapping file, as shown in the following
code snippet:

<hibernate-mapping>
<class name="Test.Authors" table="AUTHORS">
<id name="authorID" type="string">
<column name="AUTHORID" length="20" />
<generator class="assigned" />
</id>
<property name="authorName" type="string">
<column name="AUTHORNAME" length="40"
/>
</property>
<set cascade="all" name="BOOKS">
<key column="AUTHORID"/>
<one-to-many class="Test.Books"/>
</set>
</class>
<class name="Test.Books" table="BOOKS">
<id name="bookID" type="string">
<column name="BOOKID" length="20"/>
<generator class="assigned"/>
</id>
<property name="bookName" type="string">
<column name="BOOKNAME" length="40"/>
</property>
</class>
</hibernate-mapping>
Identifying Mapping of Collection (Contd.)
The <list> element:
Is used to represent a collection in which duplicate elements are allowed
and the elements are stored in ascending order.
Requires an additional index column in the collection table, which maintains
the position of each element in the collection.
The column values that define the position of each element in the collection
are referred to as the index values.
Contains attributes and sub elements similar to the <set> element.
Contains the <list-index> sub-element.
Identifying Mapping of Collection (Contd.)
For example:

package Test;
import
java.util.List;
public
{ . .class
. . .Authors
. .
private List<Books> books;
. . . . . . . . . .
public getBooks() {
List<Books>
return books;
public void setBooks(List<Books>
}
books) {
this.books = books;
}
}

The Authors class declares the books property as a collection of type,


List.
Identifying Mapping of Collection (Contd.)
Now, consider the following code snippet:

<hibernate-mapping>
. . . . . . . .
<list cascade="all" name="BOOKS">
<key column="authorid" />
<list-index column="bookid"/>
<one-to-many class="Test.Books"/>
</list>
. . . . . . .
. . . . . . .
</hibernate-mapping>

Specifies that the Books class is mapped with the BOOKS table as a List
type collection by using the <list> element.
The bookid column of the BOOKS table is defined as the column that
stores the index values.
Identifying Mapping of Collection (Contd.)
The <bag> element:
Represents a collection of objects that can have duplicates.
Does not have any order and is similar to an ArrayList collection without
an index.
Is implemented by using either the java.util.List or
java.util.Collection collection interfaces.
Is used only when the collection used in the application may contain
duplicate values and does not maintain the order of its elements.
Is mapped using the <bag> element.
Contains attributes and sub elements similar to the <set> element.
Identifying Mapping of Collection (Contd.)
For example:
package Test;
import java.util.Collection;
public class Authors
{
. . . . . . .
private Collection<Books> books;
. . . . . . .
}
public Collection<Books> getBooks() {
return books;
}
public void setBooks(Collection<Books>
books) {
this.books = books;
}
}

The preceding code, declares the books property of the Authors


class as a collection of type, Collection.
Identifying Mapping of Collection (Contd.)
To map the Books class as a bag collection in the Hibernate mapping
file, you need to use the <bag> element, as shown in the following code
snippet:
<hibernate-mapping>
. . . . . .
<bag cascade="all" name="BOOKS">
<key column="authorid" />
<one-to-many class="Test.Books"/>
</bag>
. . . . . .
</hibernate-mapping>

The <bag> element is used to map the Books class with the BOOKS
table as a collection.
The <one-to-many> element specifies the one-to-many relationship
between the AUTHORS and BOOKS tables.
Activity: Saving a Collection in Hibernate
Consider a scenario where the student have lots of address. So in this
case you need to create more number of embedded object in the
student class, which is so tedious at certain point. Therefore, to solve this
problem you have decided to use Collection. This collection can be a list,
set, map, collection, sorted set, sorted map. Application should be based
on the following guideline.
Student table contains column, such as ID, name, and address however
member variable of an address column, such as street, city, state, and pin
code are object instead of a simple data type.
Mapping Database Relationships
Consider the following tables:
Employee Employee Employee Department Department Department Department
ID Name Address ID ID Name Manager
E1 Peter London D1 D1 Sales Tom

E2 Tom New York D1 D2 HR Sam

EMPLOYEE DEPARTMENT
In this case, the EMPLOYEE table has a relationship with the
DEPARTMENT table because the department ID entered in the EMPLOYEE
table must exist in the DEPARTMENT table.
To access and store the application data in these tables you need to
create two classes, Employee and Department.
You need to map these classes with the EMPLOYEE and DEPARTMENT
tables, respectively.
In addition, you need to map the relationship between these two tables
by defining the relationship between the Employee and Department
classes. This is referred to as mapping the database relationships in a
Web application.
Mapping Database Relationships (Contd.)
At times, you may need to manage the relationships between the
persistent classes in the application.
The persistent classes are also known as entity classes.
For this, Hibernate allows you to map relationships among entity classes
with the relationships among the tables in the mapping file.
Mapping Entity Association
Hibernate allows you to map relationships among the database tables in
the Hibernate mapping file.
These relationships can be of the following types:
One-to-one
One-to-many
Many-to-many
Mapping Entity Association
One-to-one association:
Consider a scenario where to store the details of the persons, you have
created two tables named PERSON and PERSONINFO in the database
PERSONID PERSONNAME INFOID INFOID ADDRESS JOB INCOME

P1 Peter E1 E1 New York Teacher 5000

P2 Tom E2 E2 Shanghai Doctor 6000

PERSON PERSONINFO
For each person in the PERSON table, a unique record should be available in
the PERSONINFO table.
For each person, a unique record should be inserted in both the PERSON
and PERSONINFO tables.
You can link these tables by using one-to-one association.
Mapping Entity Association (Contd.)
To implement the required functionality you need to create the following
class that represents the person entity of the application:

package Test; public void setPersonID(String


public class Perso { personID) {
privat n personID; this.personID =
e Strin personName personID;
privat gPersonInfo
; }
e Strin public String
privatPerson()
public g { } getPersonName()
e
public Person(String {
personDetail;
personID) { return this.personName;
this.personID = personID; }
setPersonName(String
} personName) public void
public Person(String { this.personName
personID, String = personName;
personName, PersonInfo }
personDetail)
this.personID
{ = personID; public PersonInfo
this.personNam = getPersonDetail() {
e personName; return
this.personDetail this.personDetail;
= personDetail; }
} public void
public String setPersonDetail(PersonInf
getPersonID() return o
} this.personID; { personDetail) {
this.personDetail
= personDetail;
}
}
Mapping Entity Association (Contd.)
The personDetail property refers to an instance of the PersonInfo class.
You can create the PersonInfo class by using the following code snippet:

package Test; public void setInfoID(String


public class PersonInfo { infoID) {
private String infoID; this.infoID = infoID;
private String address; }
private String job; public String getAddress() {
private Integer income; return this.address;
public PersonInfo() { }
}
public void setAddress(String
public PersonInfo(String infoID) address) {
{ this.address = address;
this.infoID = infoID; }
} public String getJob() {
public PersonInfo(String infoID, return this.job;
String address, String job, Integer }
income) {
this.infoID = infoID; public void setJob(String job) {
this.address = address; this.job = job;
this.job = job; }
this.income = income; public Integer getIncome() {
} return this.income;
}
public String getInfoID() {
return this.infoID; public void setIncome(Integer
} income) {
this.income = income;
}
}
Mapping Entity Association (Contd.)
you need to map the one-to-one association between the classes in the
Hibernate mapping file. For this, you can use the <many-to-one> element
in the Hibernate mapping file. This element contains the following
attributes:
 name: Specifies the property name that is used to associate the classes.
 class: Specifies the fully qualified name of the associated class that provides
value for the property specified by the name attribute.
 column: Specifies the name of the foreign key column that stores the value of
the property specified by the name attribute.
 not-null: Specifies that the foreign key column cannot contain null values, if
set to true.
 cascade: Specifies that the operations performed on one table will also affect
the other table with similar updates.
 unique: Specifies that the foreign key column contains unique values. This
attribute makes the link between the tables as a one-to-one association.
Mapping Entity Association (Contd.)
To map the PERSON table with the Person class, you can use the following
code snippet in the Person.hbm.xml file:

<hibernate-mapping>
<class name="Test.Person" table="PERSON">
<id name="personID" type="string">
<column name="PERSONID" length="10" />
<generator class="assigned" />
</id>
<property name="personName" type="string">
<column name="PERSONNAME" length="40" />
</property>
<many-to-one name="personDetail"
class="Test.PersonInfo" column="INFOID" not-
null="true" cascade="all" unique="true" />
</class>
</hibernate-mapping>
Mapping Entity Association (Contd.)
One-to-many association:
Consider the scenario where you have created the application that stores
the details of authors and the books written by them in the database tables.
In this application, when a record is inserted in the AUTHORS table, a
corresponding record must be inserted in the BOOKS table that contains the
details of the books written by that author. In addition, an author might have
written multiple books. Therefore, for an author record, multiple books
records may exist in the BOOKS table.
Mapping Entity Association (Contd.)
You need to map the classes with the tables in the database that contains
the one-to-many relationship.
For this, you can use the <one-to-many> element in the
Authors.hbm.xml mapping file, as shown in the following code snippet:

<hibernate-mapping>
<class name="Test.Authors"
table="AUTHORS"> <class name="Test.Books"
<id table="Books">
name="authorID" <id name="bookID"
type="string">
<colum name="AUTHORID" type="string">
n length="20" /> <column name="bookid"
<generato length="20"/>
r class="assigned" /> <generator
</id> class="assigned"/>
<propert name="authorName" </id>
y type="string"> <property
<column name="bookName"
name="AUTHORNAME" length="40" type="string">
/> <column
</property> name="bookname" length="40"/>
<set </property>
cascade="all"
<key </class>
name="BOOKS">
column="authorid"/> </hibernate-mapping>
<one-to-many
class="Test.Books"/
>
</set>
</class>
Mapping Entity Association (Contd.)
Many-to-many association:
Consider a scenario where an university offers multiple courses. In each
course, several students can be registered. In addition, a student can register
himself or herself in multiple courses simultaneously. Therefore, you decide
to create three tables, STUDENT, COURSE, and REGISTRATION. The STUDENT
table contains student information by using the various fields, such as
StudentID, StudentName, and StudentAddress. The COURSE table
contains course information by using the various fields, such as CourseID,
CourseName, CourseDuration, and CourseFee. However, the
REGISTRATION table contains registration information by using the various
fields, such as StudentID and CourseID.
Mapping Entity Association (Contd.)
You can use the following code snippet to map the Student class with the
STUDENT table in the Student.hbm.xml file:

<hibernate-mapping>
<class name="Test.Student" table="STUDENT">
<id name="studentID" type="string">
<column length="10" name="STUDENTID"/>
<generator class="assigned"/>
</id>
<property name="studentName" type="string">
<column length="40" name="STUDENTNAME"/>
</property>
<property name="studentAddress" type="string">
<column length="100" name="STUDENTADDRESS"/>
</property>
<set cascade="all" name="courses" table="REGISTRATION">
<key column="STUDENTID"/>
<many-to-many class="Test.Course" column="COURSEID"/>
</set>
</class>
</hibernate-mapping>

In the preceding code snippet, the <many-to-many> element is used to map


the association between the Student and Course classes.
Activity: Implementing One-to-One Association in Hibernate

Consider a scenario where you need to implement one to one associate


in hibernate application. Your Application should be based on the
following guide lines:
Student table contains column, such as ID, name, and address however
member variable of an address column, such as street, city, state, and zip
code are object instead of a simple data type.
Mapping Class Inheritance
Consider a scenario where you need to develop an application that
stores the details of the books sold by a book store. Note that book store
sells different types of books, such as special edition books and books
that are published in multiple languages. Therefore, you decide to create
three classes, Books, SEBooks, and INBooks in the application. The
Books class defines the common properties of different types of books,
such as bookID, bookTitle, author, and cost. However, the SEBooks
and INBooks classes extend the Books class and define their specific
properties, such as specialfeatures and booklanguage.
Mapping Class Inheritance (Contd.)
The Java classes are associated with each other with an inheritance
relationship.
However, the inheritance relationship cannot be achieved between the
tables of a database.
Therefore, you need to explicitly map the inheritance relationship of
classes in the Hibernate mapping file while mapping the classes with the
database tables.
Hibernate provides the following types of mapping to support the
inheritance hierarchy:
Table per concrete class
Table per subclass Table
per class
Mapping Class Inheritance (Contd.)
Table per concrete class:
In the table per concrete class mapping, a table is created for each class in
the inheritance hierarchy.
Each table defines columns for all the properties of the class including the
inherited properties.
After creating the tables and the classes, you need to map them in the
Hibernate mapping file.
You can use the <union-subclass> element to map the subclasses in the
mapping file.
This element contains the following commonly used attributes:
 name: Specifies the name of the subclass.
 table: Specifies the name of the table that is to be mapped with the subclass.
Mapping Class Inheritance (Contd.)
For example:
<hibernate-mapping>
<class name="Test.Books" table="BOOKS">
......
<union-subclass name="Test.SEBooks"
table="SEBOOKS">
<property name="specialFeatures" type="string">
<column length="200" name="SPECIALFEATURES"/>
</property> </union-subclass>
<union-subclass name="Test.INBooks"
table="INBOOKS">
<property name="bookLanguage" type="string">
<column length="20" name="BOOKLANGUAGE"/>
</property> </union-subclass> </class>
</hibernate-mapping>

The <class> element provides mapping information of the super class,


Book.
The <union-subclass> element is used to map each subclass with
the corresponding tables in the database.
Mapping Class Inheritance (Contd.)
Implementing the table per concrete class mapping strategy has the
following drawbacks:
For each property mapped in the super class, the column name must be the
same in all the subclass tables.
Each table defines columns for all properties of the class including inherited
properties. This results in duplication of values.
A separate query is needed to retrieve data from each table that stores the
data of the concrete class.
A change in the super class property results in the change of the various
columns of the subclass tables.
Mapping Class Inheritance (Contd.)
Table per class:
In the table per class hierarchy mapping strategy, a single table is created for
all the classes in the inheritance hierarchy.
It eliminates the repetitive column names in the tables created for each
class in the class hierarchy.
However, you need to create an additional column in the table that
distinguishes the objects of the subclasses.
This column is referred to as the discriminator.
The values stored in this column are used to identify the rows represented
by the subclasses.
Mapping Class Inheritance (Contd.)
The following elements are used to achieve table per class hierarchy
mapping:
<discriminator>:
 Specifies the settings about the discriminator column with the help of the
following attributes:
 column: Specifies the name of the discriminator column.
 type: Specifies the data type of the values stored in the discriminator column.
<subclass>:
 Specifies the settings about the subclasses with the help of the following
attributes:
 name: Specifies the name of the subclass.
 discriminator-value: Specifies a discriminator value that is used for the
current subclass.
Mapping Class Inheritance (Contd.)
For example:

<hibernate-mapping>
<class name="Test.Books" table="BOOKDETAILS">
......
<discriminator column="BOOKTYPE" type= "string"/>
......
<subclass name="Test.SEBooks" discriminator-
value="SE">
......
</subclass>
<subclass name="Test.INBooks" discriminator-
value="IN">
......
</subclass> </class>
</hibernate-mapping>

The BOOKTYPE column of the BOOKDETAILS table is specified as the


discriminator column.
IN and SE are specified as the discriminator values that distinguish the
objects of the INBooks and SEBooks subclasses.
Mapping Class Inheritance (Contd.)
Key points of Table per class are:
The table per class hierarchy simplifies the mapping and you do not need to
create multiple tables with repetitive column names.
However, if the inheritance hierarchy increases and contains multiple
classes, the size of the table increases.
In addition, when a single table is created for all the classes in the
inheritance hierarchy, the columns that are not common among classes
contain null values.
Therefore, if the class hierarchy increases, the number of null values stored
in the table also increases. This affects the data integrity of the database.
Mapping Class Inheritance (Contd.)
Table per subclass:
In the table per subclass mapping strategy, a separate table is created for
each class.
However, columns are not repeated for the inherited properties in the table
that stores the objects of the subclass.
The table that stores the objects of the super class contains the primary key,
which is used as a foreign key in the tables that stores the objects of the
subclasses.
To achieve the table per subclass mapping, you need to use the <joined-
subclass> element in the hibernate mapping file.
Mapping Class Inheritance (Contd.)
For example:

<hibernate-mapping>
<class name="Test.Books" table="BOOKS">
......
<property name="bookTitle" type="string">
<column length="20" name="BOOKTITLE"/>
</property>
......
<joined-subclass name="Test.SEBooks" table="SEBOOKS">
<key column="seBookID"/>
<property name="specialFeatures" type="string">
<column length="200" name="SPECIALFEATURES"/>
</property> </joined-subclass>
......
</class>
</hibernate-mapping>
Mapping Class Inheritance (Contd.)
Key points of Table per subclass are:
In the table per subclass, the inheritance relationship is mapped by using
the foreign key associations in the tables.
You do not require separate queries for the tables that store objects of the
subclasses.
If the properties of the super classes change, you do not need to make any
change in the columns of the tables that store the objects of the subclasses.
Activity: Implementing Inheritance Mapping in Hibernate
Consider a scenario where you have been asked to create a Java
application that implement Table per Class inheritance mapping. The
Application should be based on the following guideline:
Employee is the super class for PermanentEmployee and
ContractEmployee classes, as shown in the following figure.

Employee
int empID
String EmpName

PermanentEmployee ContractEmployee
String companyName String ContractorName
Summary
To accomplish reusability and modularity in your application, you can:
Create a Java class to represent the shared property.
Refer the Java class from any class in the application.
The value types:
Are mapped as a component of the entity class.
Are mapped by using the <component> element in the Hibernate
mapping file.
The mapping of an entity class is configured under the <id> tag that is
used to create a unique identifier for its object. However, the component
class is configured under a <component> tag.
The commonly used collection mapping elements in the Hibernate
mapping file are:
<set>
<list>
<bag>
Summary (Contd.)
Hibernate allows you to map relationships among entity classes with the
relationships among the tables in the mapping file.
Hibernate allows you to map relationships in the following form:
One-to-one
One-to-many
Many-to-many

Hibernate provides the following types of mapping to support the


inheritance hierarchy:
Table per concrete class
Table per subclass Table
per class

Das könnte Ihnen auch gefallen