Table of contents
1.
Introduction
2.
Hibernate SortedSet Mapping Procedure
2.1.
Define RDBMS Tables
2.2.
Define POJO Classes
2.3.
Create a Hibernate Mapping File
2.3.1.
Elements of the mapping file  
2.4.
Make an Application Class
2.5.
Compilation and Implementation
3.
Frequently Asked Questions
3.1.
What is the difference between bidirectional and unidirectional mapping in Hibernate?
3.2.
What is Cascading in Hibernate?
3.3.
What is HQL?
4.
Conclusion
Last Updated: Mar 27, 2024

Hibernate SortedSet Mapping

Author Prerna Tiwari
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

A SortedSet is a java collection that contains no duplicate elements and is ordered by their natural ordering or by a comparator.

A SortedSet is mapped in the mapping table with an <set> element and initialized with java.util.TreeSet. A comparator or natural ordering can be specified as the sort attribute. Iterator traverses the set in ascending element order if we use natural ordering.

Hibernate SortedSet Mapping Procedure

Define RDBMS Tables

Consider the following scenario for the hibernate SortedSet mapping: 

We need to store employee records in the EMPLOYEE table, which will have the following structure:


create table EMPLOYEE (

   id INT NOT NULL,

   first_name VARCHAR(30),

   last_name VARCHAR(30),

   salary INT,

   PRIMARY KEY (id)

);

 

Assume that each employee can be associated with one or more certificates. A collection table index column is required for a SortedSet collection mapping. As a result, we will store certificate information in a separate table with the following structure:

 

create table CERTIFICATE (

   id INT NOT NULL,

   name VARCHAR(30),

   index INT, 

   employee_id INT,

   PRIMARY KEY (id)

);

 

EMPLOYEE and CERTIFICATE objects will have a one-to-many relationship.

Define POJO Classes

The next step in hibernate sortedSet mapping is defining POJO classes.

Let us create a POJO class Employee that will be used to persist objects related to the EMPLOYEE table and a collection of certificates in the SortedSet variable.

import java.util.*;

public class Employee {
   private int id;
   private String firstName; 
   private String lastName;   
   private int salary;
   private SortedSet certificates;
   
    public Employee() {}
   
   public Employee(String firstName, String lastName, int salary) {
      this.firstName = firstName;
      this.lastName = lastName;
      this.salary = salary;
   }


    public void setId( int id ) {
      this.id = id;
   }
   
public int getId() {
      return id;
   }

public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
    
   public String getFirstName() {
      return firstName;
   }
      
   public String getLastName() {
      return lastName;
   }
   
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   
   public int getSalary() {
      return salary;
   }
   
   public void setSalary( int salary ) {
      this.salary = salary;
   }

   public SortedSet getCertificates() {
      return certificates;
   }
   
   public void setCertificates( SortedSet certificates ) {
      this.certificates = certificates;
   }
}
You can also try this code with Online Java Compiler
Run Code


Let us now define another POJO class corresponding to the CERTIFICATE table so that certificate objects can be stored and retrieved from it. This class also implements the Comparable interface and the compareTo method, which will be used to sort the elements if sort="natural" is specified in your mapping file (see below mapping file) −


public class Certificate implements Comparable <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(Certificate that){
      final int BEFORE = -1;
      final int AFTER = 1;

      if (that == null) {
         return BEFORE;
      }

      Comparable thisCertificate = this.getName();
      Comparable thatCertificate = that.getName();

      if(thisCertificate == null) {
         return AFTER;
      } else if(thatCertificate == null) {
         return BEFORE;
      } else {
         return thisCertificate.compareTo(thatCertificate);
      }
   }
}
You can also try this code with Online Java Compiler
Run Code

Create a Hibernate Mapping File

Let's create a mapping file that tells Hibernate how to map the defined classes to the database tables. The set> element will specify the SortedSet collection's rule.

 

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate_mapping PUBLIC 
"-//Hibernate/Hibernate-Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.1.dtd"> 

<hibernate_mapping>
   <class name = "Employee" table = "EMPLOYEE">
      <meta attribute = "class-description">
         This class contains the employee detail 
      </meta>
      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>

      <set name = "certificates" cascade="all" sort="MyClass">
         <key column = "employee_id"/>
         <one-to-many class="Certificate"/>
      </set>

      <property name = "firstName" column = "first-name" type = "string"/>
      <property name = "lastName" column = "last-name" type = "string"/>
      <property name = "salary" column = "salary" type = "int"/>
   </class>

   <class name = "Certificate" table = "CERTIFICATE">
      <meta attribute = "class-description">
         This class contains 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>

 

Elements of the mapping file 
 

  • The mapping document is an XML document with <hibernate-mapping> as root element that contains two <class>> elements, one for each class.
     
  • The <class> elements specify specific mappings between Java classes and database tables. The name attribute of the class element is used to specify the Java class name, and the table attribute is used to specify the database table name.
     
  • The <meta> element is optional and can be used to generate the class description.
     
  • The <id> element maps the class's unique ID attribute to the database table's primary key. The column attribute of the id element points to the column in the table, and the name attribute refers to the property in the class. The type attribute contains the hibernate sortedset mapping type, which converts Java data to SQL data types.
     
  • Within the id element, the <generator> element automatically generates the primary key values. The class attribute of this element is put to native, which instructs hibernate to use either the identity, sequence, or Hilo algorithms to generate the primary key, depending on the capabilities of the database.
     
  • Set the relationship between the Certificate and Employee classes using the <set> element. We told Hibernate to persist the Certificate objects alongside the Employee objects by using the cascade attribute in the set> element. The name attribute is set to the parent class's SortedSet variable, which in our case, certificates. The sort attribute is set to natural to enable natural sorting or to a custom class that implements java.util.Comparator. To reverse the sorting order implemented in the Certificate class, we used a class, MyClass, that implements java.util.Comparator.
     
  • The <property> element maps a database table column to a Java class property. The element's name attribute refers to the property in the class, while the column attribute refers to the column in the database table. The type attribute contains the hibernate sortedset mapping type, which converts Java data to SQL data types.
     
  • The <key> element is that column in the CERTIFICATE table that contains the foreign key to the parent object, EMPLOYEES.
     
  • The <one-to-many> element suggests that one Employee object is related to multiple Certificate objects, and thus the Certificate object always has an Employee parent. Depending on your needs, you can use <one-to-one><many-to-one> or <many-to-many> elements. If we switched this example to a many-to-many relationship, we'd need an association table to map the parent and child objects.
     

Suppose we use the sort="natural" setting. In that case, we do not need to create a separate class because the Certificate class already implements the Comparable interface. Hibernate will compare certificate names using the compareTo() method defined in the Certificate class. However, because we use a custom comparator class, MyClass, in our mapping file, we must create this class based on our sorting algorithm. Let us use this class to perform descending sorting in this class.
 

import java.util.Comparator;

public class MyClass implements Comparator<Certificate>{
   public int compare(Certificate o1, Certificate o2) {
      final int prev = -1;
      final int next = 1;

      /* To reverse the order, multiple by -1 */
      if (o2 == null) {
         return prev * -1;
      }

      Comparable thisCertificate = o1.getName();
      Comparable thatCertificate = o2.getName();

      if(thisCertificate == null) {
         return next * 1;
      } else if(thatCertificate == null) {
         return prev * -1;
      } else {
         return thisCertificate.compareTo(thatCertificate) * -1;
      }
   }
}
You can also try this code with Online Java Compiler
Run Code

Make an Application Class

Finally, we'll create our application class, including the main() method for running the application. This application will be used to save a few Employees' records along with their certificates, and then we will perform CRUD operations.


import java.util.*;
 
import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class ManageEmployees {
   private static SessionFactory fact; 
   public static void main(String[] args) {

      try{
         fact = new Configuration().configure().buildSessionFactory();
      }
catch (Throwable e) { 
         System.err.println("Failed." + e);
         throw new ExceptionInInitializerError(e); 
      }

      ManageEmployee ManageE = new ManageEmployee();
      /* Set of certificates for the first employee */
      TreeSet set1 = new TreeSet();
      set1.add(new Certificate("MCA"));
      set1.add(new Certificate("MBA"));
      set1.add(new Certificate("BBA"));
     
      /* Add employee records in the database */
      Integer empID1 = ME.add("Rakesh", "Patel", 8000, set1);

      /* Set of certificates for the second employee */
      TreeSet set2 = new TreeSet();
      set2.add(new Certificate("BBA"));
      set2.add(new Certificate("BA"));

      /* Add another employee record in the database */
      Integer empID2 = ME.add("Harish", "Kumar", 5000, set2);

      /* List down all the employees */
      ManageE.listEmployees();

      /* Update employee's salary records */
      ManageE.updateEmployee(empID1, 5000);

      /* Delete an employee from the database */
      ManageE.deleteEmployee(empID2);

      /* List down all the employees */
      ManageE.listEmployees();

   }


   /* Adding an employee record */
   public Integer add(String f_name, String l_name, int salary, SortedSet cert){
      Session s = factory.openSession();
      Transaction t = null;
      Integer employeeID = null;
      try{
         t = session.beginTransaction();
         Employee employee = new Employee(f_name, l_name, salary);
         employee.setCertificates(cert);
         employeeID = (Integer) session.save(employee); 
         t.commit();
      }
      catch (HibernateException e) {
         if (t!=null) t.rollback();
         e.printStackTrace(); 
      }
      finally {
         s.close(); 
      }
      return employeeID;
   }


   /* List all the employees detail */
   public void listEmployees( ){
      Session s = factory.openSession();
      Transaction t = null;
      try{
         t = s.beginTransaction();
         List employees = s.createQuery("FROM Employee").list(); 
         
         for (Iterator itr1 = employees.iterator(); it1.hasNext();){
            Employee employee = (Employee) it1.next(); 
            System.out.print("First Name: " + employee.getFirstName()); 
            System.out.print(" Last Name: " + employee.getLastName()); 
            System.out.println(" Salary: " + employee.getSalary());
            SortedSet certificates = employee.getCertificates();
            for (Iterator it2 = certificates.iterator(); it2.hasNext();){
               Certificate certName = (Certificate) it2.next(); 
               System.out.println("Certificate: " + certName.getName()); 
            }
         }
         t.commit();
      }
      catch (HibernateException e) {
         if (t!=null) t.rollback();
         e.printStackTrace(); 
      }
      finally {
         s.close(); 
      }
   }
   
   /* update salary for an employee */
   public void updateEmployee(Integer EmployeeID, int salary ){
      Session s = factory.openSession();
      Transaction t = null;
      
      try{
         t = s.beginTransaction();
         Employee employee = (Employee)s.get(Employee.class, EmployeeID); 
         employee.setSalary( salary );
         s.update(employee);
         t.commit();
      }
      catch (HibernateException e) {
         if (t!=null) t.rollback();
         e.printStackTrace(); 
      }
      finally {
         s.close(); 
      }
   }
   
   /* Delete an employee from the records */
   public void deleteEmployee(Integer EmployeeID){
      Session s = factory.openSession();
      Transaction t = null;
      
      try{
         t = s.beginTransaction();
         Employee employee = (Employee)s.get(Employee.class, EmployeeID); 
         s.delete(employee); 
         t.commit();
      }
      catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      }
      finally {
         session.close(); 
      }
   }
}
You can also try this code with Online Java Compiler
Run Code

Compilation and Implementation

Before proceeding with the compilation and execution, ensure that PATH and CLASSPATH have been properly set.

  • Create the hibernate.cfg.xml configuration file.
  • As shown above, create the Employee.hbm.xml mapping file.
  • Compile the Employee.java source file.
  • Compile the Certificate.java source file.
  • Compile the MyClass.java source file.
  • Compile the ManageEmployee.java source file.
  • To run the program, run the ManageEmployee binary.


The screen would display the following result, and records would be created simultaneously in the EMPLOYEE and CERTIFICATE tables. 

As you can see, the certificates are sorted in reverse order. You can experiment by changing your mapping file, running your program, and comparing the results.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........


First Name: Rakesh Last Name: Patel Salary: 8000
Certificate: MCA
Certificate: MBA
Certificate: BBA
First Name: Harish Last Name: Kumar Salary: 5000
Certificate: BBA
Certificate: BA
First Name: Rakesh Last Name: Patel Salary: 5000
Certificate: MCA
Certificate: MBA
Certificate: BBA

 

mysql> select * from employee;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 1  | Manoj      | Kumar     |   5000 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)

 

mysql> select * from certificate;
+----+------------------+-------------+
| id | certificate_name | employee_id |
+----+------------------+-------------+
| 1  | MBA              |          1  |
| 2  | MCA             |          1  |
| 3  | BBA             |          1  |
+----+------------------+-------------+
3 rows in set (0.00 sec)

mysql>

Frequently Asked Questions

What is the difference between bidirectional and unidirectional mapping in Hibernate?

Each entity in a bidirectional relationship has a relationship field or property that refers to the other entity. An entity class's code can access its related object via the relationship field or property. An entity is said to "know" about its related object if it has a related field. They have a bidirectional relationship if the order knows what LineItem instances it has and LineItem knows what order it belongs to.

Only one entity in a unidirectional relationship has a relationship field or property that refers to the other. LineItem, for example, has a relationship field that identifies Product, but Product does not have a relationship field or property that identifies LineItem. In other words, LineItem is aware of Product, but Product is unaware of which LineItem instances refer to.

What is Cascading in Hibernate?

Cascading is Hibernate's implementation of the transitive persistence model. It is a technique that automatically propagates persistence to transient and detached sub-graphs (child objects). For example, a newly created child object of an already persistent parent object should become persistent without needing a call to the save() or persist() methods.

Cascading in Hibernate provides numerous options such as save-update, persist, merge, delete, and so on. Cascade='all' applies to all cascading options.

What is HQL?

Hibernate Query Language (HQL) is a powerful object-oriented language independent of the database. It's similar to SQL, except it uses objects instead of table names. HQL is a query language that is very simple, efficient, and flexible. It performs various operations on a relational database without the need for complex database queries.

Conclusion

In this article, we have extensively discussed the concepts of Hibernate SortedSet mapping. We started with introducing the hibernate SortedSet mapping and SortedSet in java and then discussed the mapping procedure step by step, which included defining RDBMS tables, defining POJO classes, defining hibernate sortedset mapping files, and creating application class, then concluded with compiling and execution.

We hope this blog has helped you enhance your knowledge of Hibernate SortedSet mapping. If you want to learn about JavaFX, you can learn from HibernateHibernate Map mappingHibernate Configuration, etc.

You can also refer to our Guided Path on Coding Ninjas Studio to upskill yourself in Data Structures and AlgorithmsCompetitive ProgrammingSystem Design, and many more! You may also check out the mock test series and participate in the contests hosted on Coding Ninjas Studio! For placement preparations, you must look at the problemsinterview experiences, and interview bundle.

Nevertheless, you may consider our paid courses to give your career an edge over others!

Happy Coding!

Live masterclass