Open In App

Hibernate – Map Mapping

Improve
Improve
Like Article
Like
Save
Share
Report

In a java collection, a map stores elements in key-value pairs. It will not allow duplicate elements. The map interface allows the mapped contents as a set of keys(keys alone) and a collection of values(values alone) or a set of key-value mappings. java.util.HashMap will be useful to initialize an unordered map. In the mapping table, it is denoted with the <map> element. Let us see Hibernate-Map Mapping with one too many mapping formats. Let us take the Teacher class and their corresponding qualifications. i.e. one teacher can have multiple qualifications.

Step by Step Implementation

Create MySQL tables Teacher and Qualification:

 

-- Teacher 
create table Teacher (
   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)
);
-- Qualification
create table Qualification (
   id INT NOT NULL auto_increment,
   qualification_type VARCHAR(40) default NULL,
   qualification_name VARCHAR(30) default NULL,
   teacher_id INT default NULL,
   PRIMARY KEY (id)
);
--One teacher can have multiple qualifications
--hence one to many mapping possibility

Let us see a maven-driven eclipse project to show the map mapping functionality.

Project structure:

Project structure

 

pom.xml

XML




         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>Hibernate-Map-mapping-Example</groupId>
  <artifactId>Hibernate-Map-mapping-Example</artifactId>
  <version>0.0.1-SNAPSHOT</version>
    <dependencies>
       
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.0.Final</version>
        </dependency>
       
        <!-- As we are connecting with MySQL, this is needed -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>
    </dependencies>
   
    <!-- Higher java versions are preferred, atleast 1.8 -->
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
   
</project>


First, let us see the bean classes corresponding to the tables namely Teacher and Qualification

Teacher.java

Java




import java.util.Map;
 
public class Teacher {
    private int id;
    private String firstName;
    private String lastName;
    private int salary;
     
      // One teacher can have multiple
      // qualifications and hence
      // Map is specified here
    private Map qualifications;
 
    public Teacher() {
    }
 
    public Teacher(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 Map getQualifications() {
        return qualifications;
    }
 
    public void setQualifications(Map qualifications) {
        this.qualifications = qualifications;
    }
 
}


Qualification.java

Java




public class Qualification {
 
    private int id;
    private String name;
 
    public Qualification() {}
 
    public Qualification(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; }
}


XML files that specify the relationship are as follows

teacher_qualification.hbm.xml

XML




<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD//EN"
 
<hibernate-mapping>
   <class name = "com.gfg.hibernate.pojo.Teacher" table = "Teacher">
      <meta attribute = "class-description">
         This class contains the teacher detail.
      </meta>
      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>
       
      <!-- The <map> element is used to set the relationship between Qualification
            and Teacher classes. We used the cascade attribute in the <map> element
           to tell Hibernate to persist the Qualification objects at the same time
           as the Teacher objects. The name attribute is set to the defined Map variable
           in the parent class, in our case it is qualifications. This is very important
           to specify for map mapping functionality -->
      <map name = "qualifications" cascade="all">
       
      <!-- The <key> element is the column in the Qualification table that holds the
           foreign key to the parent object ie. table Teacher.-->
      <key column = "teacher_id"/>
       
      <!-- The <index> element is used to represents the key parts of the key/value map pair.
           The key will be stored in the column qualification_type using a type of string. -->
      <index column = "qualification_type" type = "string"/>
       
      <!--  here the specification of one to many. one teacher can have multiple qualifications -->
      <!-- <one-to-one>, <many-to-one> or <many-to-many> elements based on the  requirement, it is set -->
      <one-to-many class="com.gfg.hibernate.pojo.Qualification"/>
      </map>
   
        <!-- The <property> element is used to map a Java class property to a column in the
           database table. The name attribute of the element refers to the property
           in the class and the column attribute refers to the column in the database table.
           The type attribute holds the hibernate mapping type, this mapping types will
           convert from Java to SQL data type.-->
      <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 = "com.gfg.hibernate.pojo.Qualification" table = "Qualification">
      <meta attribute = "class-description">
         This class contains the qualification records.
      </meta>
      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>
      <property name = "name" column = "qualification_name" type = "string"/>
   </class>
 
</hibernate-mapping>


We need to specify this in the main configuration file

hibernate.cfg.xml

XML




<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 
<hibernate-configuration>
    <session-factory>
       
        <!--  As we are connecting mysql, those driver classes,
              database name, username and password are specified
              Please change the information as per your requirement -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/test?serverTimezone=UTC</property>       
        <property name="connection.username">root</property>
        <property name="connection.password">admin</property>  
         
          <!--  We are going to connect teacher_qualification.hbm.xml which has the
              table information about teacher and qualification which
              is present in mysql. One teacher can have multiple qualifications  -->       
        <mapping resource="teacher_qualification.hbm.xml" />
       
    </session-factory>
   
</hibernate-configuration>


Let us do some business functionality like

  1. Adding Teachers
  2. Listing Teachers
  3. Updating the data available for Teachers
  4. Deleting the data

Configuration of code:

Java




import com.gfg.hibernate.pojo.Qualification;
import com.gfg.hibernate.pojo.Teacher;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
 
public class TeacherRepository {
    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);
        }
    }
}


Let us see the code for the addition of teachers

Java




TeacherRepository teacherRepository = new TeacherRepository();
 
// Let us have a set of qualifications
// for the professor
HashMap set = new HashMap();
set.put("Physics", new Qualification("BSC"));
set.put("ComputerScience", new Qualification("MSC"));
set.put("ProjectManagement", new Qualification("PMP"));
      
// Add teacher records in the database
Integer teacherId = teacherRepository.addData("GeekA", "GeekA", 40000, set);
 
// List down all the teacher
teacherRepository.listData();
 
// Method to add a professor details in the database
public Integer addData(String fname, String lname, int salary, HashMap qualifications){
      Session session = factory.openSession();
      Transaction tx = null;
      Integer teacherId = null;
      try{
         tx = session.beginTransaction();
         Teacher teacher = new Teacher(fname, lname, salary);
         teacher.setQualifications(qualifications);
         teacherId = (Integer) session.save(teacher);
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace();
      }finally {
         session.close();
      }
      return teacherId;
   }
 
// Method to list all the teachers detail
public void listData( ){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         // Need to specify the table name here
         List teachers = session.createQuery("FROM Teacher").list();
         for (Iterator iterator1 = teachers.iterator(); iterator1.hasNext();){
            Teacher teacher = (Teacher) iterator1.next();
            System.out.print("First Name: " + teacher.getFirstName());
            System.out.print("  Last Name: " + teacher.getLastName());
            System.out.println("  Salary: " + teacher.getSalary());
            Map teacherMap = teacher.getQualifications();
            System.out.println("Qualification: " +
              (((Qualification)teacherMap.get("Physics")).getName()));          
            System.out.println("Qualification: " +
              (((Qualification)teacherMap.get("ComputerScience")).getName()));
            System.out.println("Qualification: " +
              (((Qualification)teacherMap.get("ProjectManagement")).getName()));
         }
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace();
      }finally {
         session.close();
      }
   }


On execution of the above code, we can able to see the addition of data in the table. 

Output:

 

In the table, let us check the data

Output:

 

 

Let us update the data now

Java




// Update teacher salary records
// We need to specify the available teacher
// id to have the update to happen
teacherRepository.updateData(1, 45000);
 
// List down all the teacher
teacherRepository.listData();
 
// Method to update salary for a teacher
public void updateData(Integer teacherId, int salary ){
      Session session = factory.openSession();
      Transaction tx = null;
      try {
         tx = session.beginTransaction();
         Teacher teacher = (Teacher)session.get(Teacher.class, teacherId);
         teacher.setSalary( salary );
         session.update(teacher);
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace();
      } finally {
         session.close();
      }
   }


Let us check the output for the same

Output:

 

Next, let us see the deletion of data

Java




// Add 1 more record
TeacherRepository teacherRepository = new TeacherRepository();
      // Let us have a set of qualifications for the professor
      HashMap set = new HashMap();
      set.put("Physics", new Qualification("BSC"));
      set.put("ComputerScience", new Qualification("MSC"));
      set.put("ProjectManagement", new Qualification("PMP"));
      
      // Add teacher records in the database
      Integer teacherId = teacherRepository.addData("GeekB", "GeekB", 40000, set);
 
      // List down all the teachers
      // Here we can able to see 2 teachers
      teacherRepository.listData();
 
      // delete the specified teacher id
      // We need to specify the available
      // teacher id to have the delete to happen
      teacherRepository.deleteData(1);
      System.out.println("After deleting the 1st record..");
      teacherRepository.listData();
 
// Method to delete salary from the records
public void deleteData(Integer teacherId){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         Teacher teacher = (Teacher)session.get(Teacher.class, teacherId);
         session.delete(teacher);
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace();
      }finally {
         session.close();
      }
   }


Output:

 

 

The Complete code

Java




import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
 
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.gfg.hibernate.pojo.Qualification;
import com.gfg.hibernate.pojo.Teacher;
 
public class TeacherRepository {
   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);
      }
      TeacherRepository teacherRepository = new TeacherRepository();
       
      // Let us have a set of qualifications for the professor
      HashMap set = new HashMap();
      set.put("Physics", new Qualification("BSC"));
      set.put("ComputerScience", new Qualification("MSC"));
      set.put("ProjectManagement", new Qualification("PMP"));
      
      // Add teacher records in the database
      Integer teacherId = teacherRepository.addData("GeekA", "GeekA", 40000, set);
       
      set = new HashMap();
      set.put("Physics", new Qualification("BSC"));
      set.put("ComputerScience", new Qualification("MSC"));
      set.put("ProjectManagement", new Qualification("PMP"));
       teacherId = teacherRepository.addData("GeekB", "GeekB", 40000, set);
 
      // List down all the teachers
      teacherRepository.listData();
 
      // Update teacher salary records
      // We need to specify the available teacher
      // id to have the update to happen
      teacherRepository.updateData(1, 45000);
 
      // List down all the teacher
      teacherRepository.listData();
       
      // delete the specified teacher id
      // We need to specify the available
      // teacher id to have the delete to happen
      teacherRepository.deleteData(1);
 
      // List down all the teacher
      System.out.println("After deleting the 1st record..");
      teacherRepository.listData();
 
   }
 
// Method to add a professor details in the database
public Integer addData(String fname, String lname, int salary, HashMap qualifications){
      Session session = factory.openSession();
      Transaction tx = null;
      Integer teacherId = null;
      try{
         tx = session.beginTransaction();
         Teacher teacher = new Teacher(fname, lname, salary);
         teacher.setQualifications(qualifications);
         teacherId = (Integer) session.save(teacher);
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace();
      }finally {
         session.close();
      }
      return teacherId;
   }
 
// Method to list all the teachers detail
public void listData( ){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         List teachers = session.createQuery("FROM Teacher").list();
         for (Iterator iterator1 = teachers.iterator(); iterator1.hasNext();){
            Teacher teacher = (Teacher) iterator1.next();
            System.out.print("First Name: " + teacher.getFirstName());
            System.out.print("  Last Name: " + teacher.getLastName());
            System.out.println("  Salary: " + teacher.getSalary());
            Map teacherMap = teacher.getQualifications();
            System.out.println("Qualification: " +
              (((Qualification)teacherMap.get("Physics")).getName()));
            System.out.println("Qualification: " +
                    (((Qualification)teacherMap.get("ComputerScience")).getName()));           
            System.out.println("Qualification: " +
              (((Qualification)teacherMap.get("ProjectManagement")).getName()));
         }
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace();
      }finally {
         session.close();
      }
   }
   
// Method to update salary for a teacher
public void updateData(Integer teacherId, int salary ){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         Teacher teacher = (Teacher)session.get(Teacher.class, teacherId);
         teacher.setSalary( salary );
         session.update(teacher);
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace();
      }finally {
         session.close();
      }
   }
   
// Method to delete salary from the records
public void deleteData(Integer teacherId){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         Teacher teacher = (Teacher)session.get(Teacher.class, teacherId);
         session.delete(teacher);
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace();
      }finally {
         session.close();
      }
   }
}


Conclusion

As map can able to support key-value pair combinations, we can easily make one to many mapping relationships in Hibernate easily.



Last Updated : 25 May, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads