Learnerslesson
   JAVA   
  SPRING  
  SPRINGBOOT  
 HIBERNATE 
  HADOOP  
   HIVE   
   ALGORITHMS   
   PYTHON   
   GO   
   KOTLIN   
   C#   
   RUBY   
   C++   




Component - Set Mapping using XML

In the component mapping we have seen, an 'Employee' has one single 'Address'. But just think, an 'Employee' can also have more than one 'Address'(i.e. a permanent address and a local address).

In that case we can modify the 'Employee' class to load multiple 'Address':


class Employee{
    int id;
    String name;
    Set<Address> addressSet = new HashSet<Address> ();
    ---Getters & Setters---
}


We have used 'Set' to hold multiple 'Address'.

Set<Address> addressSet = new HashSet<Address> ();
Note : While dealing with components we have put the 'Employee' record and its corresponding 'Address' record in the same table i.e. EMPLOYEE table. But in this case we can have multiple 'Address' for a single 'Employee'. Although, 'Address' is a Component still we need to have two different tables i.e 'EMPLOYEE' AND 'ADDRESS' to avoid data duplication.

Similarly, the 'Address' class looks like :


class Address{
    String streetName;
    String city;
    String pinCode;
    ---Getters & Setters---
 }

Let us follow the below steps:

1. Firstly in the mapping file we need to tell Hibernate that the 'Address' class has to be treated as a 'Set'.


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

   <id name = "empId" type = "int">
    <column name = "ID">
   <id>
   <property name = "name" type = "string">
    <column name = "NAME">
   </property>

   <set name="addressSet" table="ADDRESS">
    <key column="EMP_ID">
    <composite-element class="Address">
     <property name = "streetName" type = "string">
      <column name = "STREET_NAME">
     </property>

     <property name = "city" type = "string">
      <column name = "CITY">
     </property>

     <property name = "pinCode" type = "string">
      <column name = "PIN_CODE">
     </property>
    </composite-element>
   </set>

  </class>
</hibernate-mapping>

In the above statement we have informed Hibernate that multiple 'Address' has to be added to the 'ADDRESS' table and we have used 'Set' of java to achieve that.

<set name="addressSet" table="ADDRESS">

Now, to create a link between the 'EMPLOYEE' and 'ADDRESS' table we have used the primary key 'ID' in the 'ADDRESS' table to establish a primary key - foreign key relationship.

<key column="ID">

Then we have informed Hibernate about the 'Address' class using the '<composite-element>' tag of Hibernate.

<composite-element class="Address">
  <property name = "streetName" type = "string">
   <column name = "STREET_NAME">
  </property>
  ...
  ...
</composite-element>

2. Next, we will be writing the main class where we will be saving the 'Employee' data and its corresponding 'Address' data to the database using Hibernate.


import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateSave {
   public static void main(String[] args) {

    static SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
    Session session = sessionFactory.openSession();
    session.beginTransaction();

    Set <Address> addressSet = new HashSet <Address>();

    Address localAddress = new Address();
    localAddress.setStreetName("Walls Street");
    localAddress.setCity("Delhi");
    localAddress.setPinCode("110012");

    addressSet.add(localAddress);

    Address permanentAddress = new Address();
    permanentAddress.setStreetName("Murugeshpalya");
    permanentAddress.setCity("Bangalore");
    permanentAddress.setPinCode("560019");

    addressSet.add(permanentAddress);

    Employee employee = new Employee();
    employee.setId(1);
    employee.setName("Joe");
    employee.setAddressSet(addressSet);
    session.save(employee);

    session.getTransaction().commit();

    session.close();
    sessionFactory.close();
  }
}

So, in the above example we have created two 'Address'.

First is the local address of the Employee.

Address localAddress = new Address();
localAddress.setStreetName("Walls Street");
localAddress.setCity("Delhi");
localAddress.setPinCode("110012");

Second is the Permanent Address of the Employee.

Address permanentAddress = new Address();
permanentAddress.setStreetName("Murugeshpalya");
permanentAddress.setCity("Bangalore");
permanentAddress.setPinCode("560019");

And since the Addresses are stored in 'Set'. We have created a 'Set' object

Set<Address> addressSet = new HashSet <Address>();

to store the 'localAddress'

addressSet.add(localAddress)

and 'permanentAddress'.

addressSet.add(permanentAddress);

And finally we need to add the Set 'addressSet' to the 'Employee' object.

employee.setAddressSet(addressSet);

EMPLOYEE

ID NAME
1 Joe

ADDRESS

ID STREET_NAME CITY PIN_CODE
1 Walls street Delhi 110012
1 Murugeshpalya Bangalore 560019