Detail the List mapping table and Bag mapping in the Hibernate framework of Java

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

List the mapping table
A List is a Java collection of elements stored in a sequence and allows for repeating elements. The user of this interface can precisely control where each element in the list is inserted. Users can access elements through their integer index and search for elements in the list. More formally, lists usually allow for elements e1 and e2, making e1.equals (e2), which usually allow multiple null elements if they allow null elements.

The List List is mapped to the mapping table. List> Element and initialize the java.util.ArrayList.

Define RDBMS tables:
Consider a case where the EMPLOYEE records need to be stored in the EMPLOYEE table, which will have 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. The List collection mapping requires an index column in a collection table. The index column defines the location of the elements in the collection. 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,
  idx INT default NULL, 
  employee_id INT default NULL,
  PRIMARY KEY (id)
);

There will be a one-to-one relationship between the EMPLOYEE and the certificate object.

Define POJO classes:
Let's implement a POJO class EMPLOYEE that will be used to hold a collection of objects in the EMPLOYEE table and list variables with certificates.


import java.util.*;

public class Employee {
  private int id;
  private String firstName; 
  private String lastName;  
  private int salary;
  private List 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 List getCertificates() {
   return certificates;
  }
  public void setCertificates( List certificates ) {
   this.certificates = certificates;
  }
}

We need the corresponding certificate table to define another POJO class so that the certificate object can store and retrieve the certificate table.


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

Define Hibernate mapping file:
Let's develop a mapping file that specifies how Hibernate defines classes that map to database tables. < List> The element will be used to define the rules for using the List collection. Table indexes are of integer type always and use < The list - index> The element defines the mapping.


<?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>
   <list name="certificates" cascade="all">
     <key column="employee_id"/>
     <list-index column="idx"/>
     <one-to-many class="Certificate"/>
   </list>
   <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. We save the file employee.hbm.xml in our mapping file. You are 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.

< 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.

< List> The element is used to set the relationship between the certificate and the Employee class. We use the cascade attribute < List> Element to tell Hibernate to save the object of the certificate as an Employee object. The name property is set to the Listvariable defined in the parent class, which in our case is the certificate.

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

< The list - index> The element definition is used to hold the element's position and map to the index column in the collection table. The index of the persistent list starts from zero. You can change this, for example, in your mapping < The list - the index base = "1"... / > .

< One - to - many> The element represents an Employee object that involves many certificates, and therefore the certificate object must have a worker parent associated with it. You can use any and < according to your needs. One - to - one> , < Many - to - one> Or < Many - to - many> This element right here. If we change this example to use a many-to-many relationship, we need a mapping from the associated table to the parent and child objects.

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();
   
   ArrayList set1 = new ArrayList();
   set1.add(new Certificate("MCA"));
   set1.add(new Certificate("MBA"));
   set1.add(new Certificate("PMP"));
   
   
   Integer empID1 = ME.addEmployee("Manoj", "Kumar", 4000, set1);

   
   ArrayList set2 = new ArrayList();
   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, ArrayList 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());
      List 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. Make sure you 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. 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: MCA
Certificate: MBA
Certificate: PMP
First Name: Dilip Last Name: Kumar Salary: 3000
Certificate: BCA
Certificate: BA
First Name: Manoj Last Name: Kumar Salary: 5000
Certificate: MCA
Certificate: MBA
Certificate: PMP

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


mysql> select * from EMPLOYEE;

+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 51 | Manoj   | Kumar   |  5000 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)


mysql> select * from CERTIFICATE;

+----+------------------+------+-------------+
| id | certificate_name | idx | employee_id |
+----+------------------+------+-------------+
| 6 | MCA       |  0 |     51 |
| 7 | MBA       |  1 |     51 |
| 8 | PMP       |  2 |     51 |
+----+------------------+------+-------------+
3 rows in set (0.00 sec)

Alternatively, you can map Java arrays instead of a list. The mapping of an array is almost identical to the previous example, except with different element and attribute names (< Array> And < Array - index>) . However, as mentioned earlier, Hibernate applications rarely use arrays.

'the mapping
Bag is a Java collection that stores elements in no order, but allows duplicate elements in a list. A Bag is a random grouping of objects in a list.

The Collection Collection is mapped in the mapping table < Bag> Element and initialization with java.util.ArrayList.
In the following example, the RDBMS tables and POJO classes are still defined above.
Define Hibernate mapping file:
Let's develop a mapping file that tells Hibernate how to define classes that map to database tables. < Bag> The element will be used to define the set rules 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>
   <bag name="certificates" cascade="all">
     <key column="employee_id"/>
     <one-to-many class="Certificate"/>
   </bag>
   <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. We save the mapping file employee.hbm.xml. We've already familiarized ourselves with most of the mapping details, but let's see all the elements in the mapping file again:

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.

< Bag> The element is used to set the relationship between the certificate and the Employee class. We use the < of the cascade attribute. Bag> The high element tells Hibernate to save the object of the certificate as an Employee object. The name attribute is set to the definedCollection variable in the parent class, which in our case is the certificate.

< Key> The element is the parent object that contains 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 an Employee parent class associated with it. Can be used 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 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();
   
   ArrayList set1 = new ArrayList();
   set1.add(new Certificate("MCA"));
   set1.add(new Certificate("MBA"));
   set1.add(new Certificate("PMP"));
   
   
   Integer empID1 = ME.addEmployee("Manoj", "Kumar", 4000, set1);

   
   ArrayList set2 = new ArrayList();
   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, ArrayList 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());
      Collection 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:

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: MCA
Certificate: MBA
Certificate: PMP
First Name: Dilip Last Name: Kumar Salary: 3000
Certificate: BCA
Certificate: BA
First Name: Manoj Last Name: Kumar Salary: 5000
Certificate: MCA
Certificate: MBA
Certificate: PMP

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


mysql> select * from EMPLOYEE;

+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 53 | Manoj   | Kumar   |  5000 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)


mysql> select * from CERTIFICATE;


+----+------------------+-------------+
| id | certificate_name | employee_id |
+----+------------------+-------------+
| 11 | MCA       |     53 |
| 12 | MBA       |     53 |
| 13 | PMP       |     53 |
+----+------------------+-------------+
3 rows in set (0.00 sec)

Related articles: