Detail the set mapping set and SortedSet mapping in the Hibernate framework of Java

  • 2020-04-01 04:30:10
  • OfStack

The Set
A Set is a Java collection that does not contain any duplicate elements. More formally, Set contains no elements for e1 and e2, making e1.equals (e2), and at most one empty element. So to be added to a set of objects must implement the equals() and hashCode() methods so that Java can determine whether any two elements/objects are the same.

The set is mapped to the mapping table. Set> Element and is initialized in a java.util.hashset. You can use a Set Set in a class where there is an element in the Set that does not need to be repeated.

Define RDBMS tables:
Consider a case where we need our EMPLOYEE records to be stored in the EMPLOYEE table, with the following structure:


create table EMPLOYEE (
 id INT NOT NULL auto_increment,
 first_name VARCHAR(20) default NULL,
 last_name VARCHAR(20) default NULL,
 salary  INT default NULL,
 PRIMARY KEY (id)
);

In addition, it is assumed that each employee can have one or more certificates related to him or her. Therefore, we will store the information about the certificate in a separate table with the following structure:


create table CERTIFICATE (
 id INT NOT NULL auto_increment,
 certificate_name VARCHAR(30) default NULL,
 employee_id INT default NULL,
 PRIMARY KEY (id)
);

There will be a relationship between multiple EMPLOYEE and the certificate object:

Define POJO classes:
Let's implement that our POJO class employees will be used to save the collection of objects in the EMPLOYEE table and Settings variables with credentials.


import java.util.*;

public class Employee {
 private int id;
 private String firstName; 
 private String lastName; 
 private int salary;
 private Set certificates;

 public Employee() {}
 public Employee(String fname, String lname, int salary) {
  this.firstName = fname;
  this.lastName = lname;
  this.salary = salary;
 }
 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 getSalary() {
  return salary;
 }
 public void setSalary( int salary ) {
  this.salary = salary;
 }

 public Set getCertificates() {
  return certificates;
 }
 public void setCertificates( Set certificates ) {
  this.certificates = certificates;
 }
}

Now let's define the CERTIFICATE for the corresponding table of another POJO class, so that the CERTIFICATE object can store and retrieve the CERTIFICATE table. This class should also implement both the equals () and hashCode () methods, allowing Java to determine whether any two elements/objects are the same.


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 boolean equals(Object obj) {
  if (obj == null) return false;
  if (!this.getClass().equals(obj.getClass())) return false;

  Certificate obj2 = (Certificate)obj;
  if((this.id == obj2.getId()) && (this.name.equals(obj2.getName())))
  {
   return true;
  }
  return false;
 }
 public int hashCode() {
  int tmp = 0;
  tmp = ( id + name ).hashCode();
  return tmp;
 }
}

Define Hibernate mapping file:
Let's develop a mapping file that specifies how Hibernate defines classes that map to database tables. < SET> The element will be used to define the rules used to set the collection.


<?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="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">
   <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 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>

Format in the mapping file that should be saved. Classname> . HBM. XML. Save the file employee.hbm.xml in the mapping file. Now that you're familiar with most of the mapping details, all the elements in the mapping file:

Mapping documents are available with < Hibernate - mapping> Contains 2 < for each class; Class> XML document for the root element of the element.

In < Class> The element is used to define a database table specific mapping from a Java class. The Java class name is specified using the name attribute of the class element and the database table name using the table attribute.

< Meta> The element is an optional element that can be used to create a description of the class.

< Id> The element maps the unique ID attribute in the class to the primary key of the database table. The name attribute of the id element refers to the class of the attribute and the column attribute refers to the column in the database table. The type attribute holds the Hibernate mapping type that will be converted from Java to SQL data type.

In the id element < Generator> The element is used to automatically generate primary key values. Set the class attribute of the generated element to the original for Hibernate to pick up, whether it's identity, sequence, or hilo's algorithm to create the primary key based on the underlying database's supporting capabilities.

< Property> The element is used to map attributes of a Java class to columns in a database table. The name attribute of the element refers to the class of the attribute and the column attribute refers to the column in the database table. The type attribute holds the Hibernate mapping type that will be converted from Java to SQL data type.

< SET> The element is new and has been introduced to set the relationship between the CERTIFICATE and Employee classes. We use the < in the cascade attribute. Set> Element to tell Hibernate to save the CERTIFICATE object as an Employee object. The name attribute is set to the defined Settings variable in the parent class, which in our case is CERTIFICATE. For each set of variables, we need to define a separate set of elements in the mapping file.

< Key> The element is the parent object containing the foreign key, which is the column in the certificate table. Table EMPLOYEE.

< One - to - many> The element represents an Employee object that involves many certificates, and therefore the certificate object must have a parent Employee associated with it. You can use any and < as needed. One - to - one> , < Many - to - one> Or < Many - to - many> This element right here.

Create an application class:
Finally, we will create the main() method of the application class to run the application. We'll use the application to save some employee records along with credentials, and then we'll request records on CRUD operations.


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

public class ManageEmployee {
 private static SessionFactory factory; 
 public static void main(String[] args) {
  try{
   factory = new Configuration().configure().buildSessionFactory();
  }catch (Throwable ex) { 
   System.err.println("Failed to create sessionFactory object." + ex);
   throw new ExceptionInInitializerError(ex); 
  }
  ManageEmployee ME = new ManageEmployee();
  
  HashSet set1 = new HashSet();
  set1.add(new Certificate("MCA"));
  set1.add(new Certificate("MBA"));
  set1.add(new Certificate("PMP"));
  
  
  Integer empID1 = ME.addEmployee("Manoj", "Kumar", 4000, set1);

  
  HashSet set2 = new HashSet();
  set2.add(new Certificate("BCA"));
  set2.add(new Certificate("BA"));

  
  Integer empID2 = ME.addEmployee("Dilip", "Kumar", 3000, set2);

  
  ME.listEmployees();

  
  ME.updateEmployee(empID1, 5000);

  
  ME.deleteEmployee(empID2);

  
  ME.listEmployees();

 }

 
 public Integer addEmployee(String fname, String lname, 
           int salary, Set cert){
  Session session = factory.openSession();
  Transaction tx = null;
  Integer employeeID = null;
  try{
   tx = session.beginTransaction();
   Employee employee = new Employee(fname, lname, salary);
   employee.setCertificates(cert);
   employeeID = (Integer) session.save(employee); 
   tx.commit();
  }catch (HibernateException e) {
   if (tx!=null) tx.rollback();
   e.printStackTrace(); 
  }finally {
   session.close(); 
  }
  return employeeID;
 }

 
 public void listEmployees( ){
  Session session = factory.openSession();
  Transaction tx = null;
  try{
   tx = session.beginTransaction();
   List employees = session.createQuery("FROM Employee").list(); 
   for (Iterator iterator1 = 
       employees.iterator(); iterator1.hasNext();){
   Employee employee = (Employee) iterator1.next(); 
   System.out.print("First Name: " + employee.getFirstName()); 
   System.out.print(" Last Name: " + employee.getLastName()); 
   System.out.println(" Salary: " + employee.getSalary());
   Set certificates = employee.getCertificates();
   for (Iterator iterator2 = 
       certificates.iterator(); iterator2.hasNext();){
     Certificate certName = (Certificate) iterator2.next(); 
     System.out.println("Certificate: " + certName.getName()); 
   }
   }
   tx.commit();
  }catch (HibernateException e) {
   if (tx!=null) tx.rollback();
   e.printStackTrace(); 
  }finally {
   session.close(); 
  }
 }
 
 public void updateEmployee(Integer EmployeeID, int salary ){
  Session session = factory.openSession();
  Transaction tx = null;
  try{
   tx = session.beginTransaction();
   Employee employee = 
     (Employee)session.get(Employee.class, EmployeeID); 
   employee.setSalary( salary );
   session.update(employee);
   tx.commit();
  }catch (HibernateException e) {
   if (tx!=null) tx.rollback();
   e.printStackTrace(); 
  }finally {
   session.close(); 
  }
 }
 
 public void deleteEmployee(Integer EmployeeID){
  Session session = factory.openSession();
  Transaction tx = null;
  try{
   tx = session.beginTransaction();
   Employee employee = 
     (Employee)session.get(Employee.class, EmployeeID); 
   session.delete(employee); 
   tx.commit();
  }catch (HibernateException e) {
   if (tx!=null) tx.rollback();
   e.printStackTrace(); 
  }finally {
   session.close(); 
  }
 }
}

Compile and execute:
Here are the steps to compile and run the above application. Be sure to set the PATH and CLASSPATH appropriately before compiling and executing.

The configuration section in the create hibernate.cfg.xml configuration file explains. Create the employee.hbm.xml mapping file, as shown in the figure above. Create the employee.java source file, as shown in the figure above, and compile it. Create the Certificate. Java source file, as shown in the figure above, and compile it. Create the manageemployee.java source file, as shown in the figure above, and compile it. Execute the ManageEmployee binary to run the program.

The following results are obtained on the screen and records are created in both the employee and certificate tables.


$java ManageEmployee


.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Manoj Last Name: Kumar Salary: 4000
Certificate: MBA
Certificate: PMP
Certificate: MCA
First Name: Dilip Last Name: Kumar Salary: 3000
Certificate: BCA
Certificate: BA
First Name: Manoj Last Name: Kumar Salary: 5000
Certificate: MBA
Certificate: PMP
Certificate: MCA

If you check the employee and certificate forms, you should record:


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 | PMP    |   1 |
| 3 | MCA    |   1 |
+----+------------------+-------------+
3 rows in set (0.00 sec)


mysql>

SortedSet
SortedSet is a Java collection that does not contain any repeating elements and elements used to provide their natural order, or sorted by a comparator.

A SortedSet map in the mapping table < Set> Element and java.util.TreeSet. The sort property can be set to either a comparator or a natural order. If natural order is used, then the collection elements traversed by its iterator are arranged in ascending order.

We will still use the RDBMS table defined in the example above and have a relationship between the multi-employee and certificate objects, as well as the POJO classes.

Let's implement that POJO class employees will be used to store the collection of objects in the EMPLOYEE table and SortedSet variables with certificates.

Now let's define the certificate for the corresponding table of another POJO class, so that the certificate object can store and retrieve the certificate table. This class should also implement the Comparable interface and the compareTo method will be used to set sort="natural" in the case of the mapping file (see the mapping file below) where the element is sorted.


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);
  }
 }
}

Define Hibernate mapping file:
Let's develop a mapping file that specifies how Hibernate defines classes that map to database tables. The < Set> The element will be used to define the rules for the SortedSet collection to be 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="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 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>

Format in the mapping file < Classname> .hbm.xml, save the file employee.hbm.xml in the mapping file. We've already familiarized ourselves with most of the mapping details, but let's look at all the elements in the mapping file:

Mapping documents are available with < Hibernate - mapping> Contains 2 < for each class; Class> XML document for the root element of the element.

< Class> The element is used to define a database table specific mapping from a Java class. The Java class name is specified using the name attribute of the class element and the database table name using the table attribute.

< Meta> The element is an optional element that can be used to create a description of the class.

< Id> The element maps the unique ID attribute in the class to the primary key of the database table. The name attribute of the id element refers to the class of the attribute and the column attribute refers to the column in the database table. The type attribute holds the Hibernate mapping type that will be converted from Java to SQL data type.

In the id element < Generator> The element is used to automatically generate primary key values. Set the class attribute of the generated element to native so that Hibernate can pick up the algorithm in either identity, sequence, or hilo to create the primary key based on the underlying database's supporting capabilities.

< Property> The element is used to map attributes of a Java class to columns in a database table. The name attribute of the element refers to the class of the attribute and the column attribute refers to the column in the database table. The type attribute holds the Hibernate mapping type that will be converted from Java to SQL data type.

< Set> The element is used to set the relationship between the certificate and the Employee class. We use the < in the cascade attribute. Set> Element to tell Hibernate to save the object of the certificate as an Employee object. The name property is set to the variable of the SortedSet defined in the parent class, which in our case is the certificate. The sort property can be set to natural with natural sort or to a custom class implementation as java.util.Comparator. We have used a class MyClass that is implemented to reverse the sort order of the certificate class implementation for the java.util.Comparator.

< Key> The element is the parent object that contains the foreign key, which is the column in the certificate table. Table EMPLOYEE.

The < One - to - many> The element represents an Employee object that involves many certificates, and therefore the certificate object must have a parent Employee associated with it. You can use any and < as needed. One - to - one> , < Many - to - one> Or < Many - to - many> This element right here.

If you use the sort="natural" setting, you don't need to create a separate class because the certificate class already implements the Comparable interface and hibernate USES the compareTo (defined in the certificate class as the comparison certificate name) method. However, we are using our mapping file custom comparator class MyClass, so we must implement the sorting algorithm based on this class. I'm going to use this class to sort in this class when I'm descending.


import java.util.Comparator;

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

  
  if (o2 == null) {
   return BEFORE * -1;
  }

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

  if(thisCertificate == null) {
   return AFTER * 1;
  } else if(thatCertificate == null) {
   return BEFORE * -1;
  } else {
   return thisCertificate.compareTo(thatCertificate) * -1;
  }
 }
}

Create an application class:
Finally, we will create the main () method of the application class to run the application. We will use this application to save some employee records along with certificates, and then we will apply for records on CRUD operations.


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

public class ManageEmployee {
 private static SessionFactory factory; 
 public static void main(String[] args) {
  try{
   factory = new Configuration().configure().buildSessionFactory();
  }catch (Throwable ex) { 
   System.err.println("Failed to create sessionFactory object." + ex);
   throw new ExceptionInInitializerError(ex); 
  }
  ManageEmployee ME = new ManageEmployee();
  
  TreeSet set1 = new TreeSet();
  set1.add(new Certificate("MCA"));
  set1.add(new Certificate("MBA"));
  set1.add(new Certificate("PMP"));
  
  
  Integer empID1 = ME.addEmployee("Manoj", "Kumar", 4000, set1);

  
  TreeSet set2 = new TreeSet();
  set2.add(new Certificate("BCA"));
  set2.add(new Certificate("BA"));

  
  Integer empID2 = ME.addEmployee("Dilip", "Kumar", 3000, set2);

  
  ME.listEmployees();

  
  ME.updateEmployee(empID1, 5000);

  
  ME.deleteEmployee(empID2);

  
  ME.listEmployees();

 }

 
 public Integer addEmployee(String fname, String lname, 
          int salary, SortedSet cert){
  Session session = factory.openSession();
  Transaction tx = null;
  Integer employeeID = null;
  try{
   tx = session.beginTransaction();
   Employee employee = new Employee(fname, lname, salary);
   employee.setCertificates(cert);
   employeeID = (Integer) session.save(employee); 
   tx.commit();
  }catch (HibernateException e) {
   if (tx!=null) tx.rollback();
   e.printStackTrace(); 
  }finally {
   session.close(); 
  }
  return employeeID;
 }

 
 public void listEmployees( ){
  Session session = factory.openSession();
  Transaction tx = null;
  try{
   tx = session.beginTransaction();
   List employees = session.createQuery("FROM Employee").list(); 
   for (Iterator iterator1 = 
       employees.iterator(); iterator1.hasNext();){
   Employee employee = (Employee) iterator1.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 iterator2 = 
       certificates.iterator(); iterator2.hasNext();){
     Certificate certName = (Certificate) iterator2.next(); 
     System.out.println("Certificate: " + certName.getName()); 
   }
   }
   tx.commit();
  }catch (HibernateException e) {
   if (tx!=null) tx.rollback();
   e.printStackTrace(); 
  }finally {
   session.close(); 
  }
 }
 
 public void updateEmployee(Integer EmployeeID, int salary ){
  Session session = factory.openSession();
  Transaction tx = null;
  try{
   tx = session.beginTransaction();
   Employee employee = 
     (Employee)session.get(Employee.class, EmployeeID); 
   employee.setSalary( salary );
   session.update(employee);
   tx.commit();
  }catch (HibernateException e) {
   if (tx!=null) tx.rollback();
   e.printStackTrace(); 
  }finally {
   session.close(); 
  }
 }
 
 public void deleteEmployee(Integer EmployeeID){
  Session session = factory.openSession();
  Transaction tx = null;
  try{
   tx = session.beginTransaction();
   Employee employee = 
     (Employee)session.get(Employee.class, EmployeeID); 
   session.delete(employee); 
   tx.commit();
  }catch (HibernateException e) {
   if (tx!=null) tx.rollback();
   e.printStackTrace(); 
  }finally {
   session.close(); 
  }
 }
}

After compiling and executing, the following results are obtained on the screen, and records are created in both the employee and certificate tables. You can see that the certificates are sorted in reverse order. You can try this by changing the mapping file by simply setting sort="natural" and executing the program and comparing the results.


$java ManageEmployee

.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Manoj Last Name: Kumar Salary: 4000
Certificate: PMP
Certificate: MCA
Certificate: MBA
First Name: Dilip Last Name: Kumar Salary: 3000
Certificate: BCA
Certificate: BA
First Name: Manoj Last Name: Kumar Salary: 5000
Certificate: PMP
Certificate: MCA
Certificate: MBA

If you check the employee and certificate forms, you should record:


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 | PMP    |   1 |
| 3 | MCA    |   1 |
+----+------------------+-------------+
3 rows in set (0.00 sec)


Related articles: