Hibernate O-R Mapping using SortedMap
In this article, we'll take a look at Hibernate O/R collection mappings and learn how to map a SortedMap to entities stored in a database.
Hibernate is a complete solution for the persistence module in a Java project. It handles the application interaction with the database, leaving the developer free to concentrate more on business logic and solving complex problems.
So far, we have seen basic O/R mapping, Set, List mappings using hibernate but there are more important mappings like inserting List and ArrayList Collections in Database.
Collection Mapping
If an entity or class has multiple values for a particular property or variable, then we can map those values using one of the collection interfaces available in Java. Hibernate can persist instances of java.util.Map, java.util.Set, java.util.SortedMap, java.util.SortedSet, java.util.List, and any array of persistent entities or values.
The collection we want to use depends on the behavior we want to introduce like if we want to store any value, we will use List and ArrayList.
Let’s look at each of these with examples here.
java.util.TreeMap
A SortedMap is a similar java collection as Map that stores elements in key-value pairs and provides a total ordering on its keys. Duplicate elements are not allowed in the map. The map is ordered according to the natural ordering of its keys, or by a Comparator typically provided at SortedMap creation time.
A SortedMap is mapped with a <map> element in the mapping table and an ordered map can be initialized with java.util.TreeMap.
Defining RDBMS table
We start by defining our RDBMS table. We will again use our Student table here:
create table STUDENT (
id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
grade DECIMAL(3,1) default NULL,
PRIMARY KEY (id)
);
Now, let us assume that each student can have multiple certifications involved. So we will store certificate related information in a separate table which has the following schema:
create table CERTIFICATE (
id INT NOT NULL auto_increment,
certificate_type VARCHAR(40) default NULL,
certificate_name VARCHAR(30) default NULL,
student_id INT default NULL,
PRIMARY KEY (id)
);
POJO for Entities
Let us have a look at our Student entity POJO once again:
public class Student {
private int id;
private String firstName;
private String lastName;
private float grade;
private SortedMap certificates;
public Student() {}
public Student(String fname, String lname, float grade) {
this.firstName = fname;
this.lastName = lname;
this.grade = grade;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getGrade() {
return grade;
}
public void setGrade( float grade ) {
this.grade = grade;
}
public SortedMap getCertificates() {
return certificates;
}
public void setCertificates( SortedMap certificates ) {
this.certificates = certificates;
}
}
Next, we define our second POJO class for the CERTIFICATE table so that certificate objects can be saved and read from the CERTIFICATE table. This class should implement both the equals() and hashCode() methods so that Java can determine if two elements/objects are equal. This class should also implement Comparable interface and compareTo method which will be used to sort the elements in case we set sort="natural" in our mapping file.
public class Certificate {
private int id;
private String name;
public Certificate() {}
public Certificate(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
public int compareTo(String that){
final int BEFORE = -1;
final int AFTER = 1;
if (that == null) {
return BEFORE;
}
Comparable thisCertificate = this;
Comparable thatCertificate = that;
if(thisCertificate == null) {
return AFTER;
} else if(thatCertificate == null) {
return BEFORE;
} else {
return thisCertificate.compareTo(thatCertificate);
}
}
}
Now, as our POJO classes are ready, we define our Hibernate mapping file.
Hibernate Mapping files
In this file, the <list> element will be used to define the rule for the ArrayList collection used.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Student" table="STUDENT">
<meta attribute="class-description">
This class contains the student detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<map name="certificates" cascade="all" sort="MyClass">
<key column="student_id"/>
<index column="certificate_type" type="string"/>
<one-to-many class="Certificate"/>
</map>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="grade" column="grade" type="float"/>
</class>
<class name="Certificate" table="CERTIFICATE">
<meta attribute="class-description">
This class contains the certificate records.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="name" column="certificate_name" type="string"/>
</class>
</hibernate-mapping>
The <map> element is used to set the relationship between the Certificate and Student classes. We used the cascade attribute in the <map> element to tell Hibernate to persist the Certificate objects at the same time as the Student objects. The name attribute is set to the defined SortedMap variable in the parent class, in our case it is certificates. The sort attribute can be set to natural to have natural sorting or it can be set to a custom class implementing java.util.Comparator. We have used a class called MyClass which implements java.util.Comparator to reverse the sorting order implemented in the Certificate class.
The <index> element is used to represents the key parts of the key/value map pair. The key will be stored in the column certificate_type using a type of string.
The <key> element is the column in the CERTIFICATE table that holds the foreign key to the parent object ie. table STUDENT.
The <one-to-many> element indicates that one Student object relates to many Certificate objects and, as such, the Certificate object must have a Student parent object associated with it. We can use either <one-to-one>, <many-to-one> or <many-to-many> elements based on our requirement.
We need to define Comparator here as well, just like we did in Map mapping.
import java.util.Comparator;
public class MyClass implements Comparator <String>{
public int compare(String o1, String o2) {
final int BEFORE = -1;
final int AFTER = 1;
/* To reverse the sorting order, multiple by -1 */
if (o2 == null) {
return BEFORE * -1;
}
Comparable thisCertificate = o1;
Comparable thatCertificate = o2;
if(thisCertificate == null) {
return AFTER * 1;
} else if(thatCertificate == null) {
return BEFORE * -1;
} else {
return thisCertificate.compareTo(thatCertificate) * -1;
}
}
}
Application class
Finally, we will create our application class with the main() method to run the application. We will use this application to save a few Student's records along with their certificates and then we will apply CRUD operations on those records.
TreeMap set1 = new TreeMap();
set1.put("ComputerScience", new Certificate("MCA"));
set1.put("BusinessManagement", new Certificate("MBA"));
set1.put("ProjectManagement", new Certificate("PMP"));
/* Add student records in the database */
Integer studentID1 =
ManageStudent.addStudent("Liran", "Heim", 4000, list1);
Clearly, it was simple to create Treemap elements and store them in the database.
Now, if we check our database, we will have following results in our Student and Certificate tables.
mysql> select * from student;
+----+------------+-----------+--------+
| id | first_name | last_name | grade |
+----+------------+-----------+--------+
| 1 | Liran | Heim | 5.1 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)
mysql>select * from CERTIFICATE;
+----+--------------------+------------------+-------------+
| id | certificate_type | certificate_name | employee_id |
+----+--------------------+------------------+-------------+
| 16 | ProjectManagement | PMP | 12 |
| 17 | BusinessManagement | MBA | 12 |
| 18 | ComputerScience | MCA | 12 |
+----+--------------------+------------------+-------------+
3 rows in set (0.00 sec)
Conclusion
In this article, we studied Hibernate O/R mappings using SortedMap mappings and built the last example once again but this time, using Hibernate collection SortedMap mappings.
Recent Stories
Top DiscoverSDK Experts
Compare Products
Select up to three two products to compare by clicking on the compare icon () of each product.
{{compareToolModel.Error}}
{{CommentsModel.TotalCount}} Comments
Your Comment