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




Component Mapping using XML

Let us understand Component with the below example:

In our earlier example we have seen the 'Employee' class:


class Employee{
  int id;
  String 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;
  }
}


Now, other than the 'id' and 'name' field, the Employee can also have an address. And as we all know the address will contain 'streetName', 'city' and 'pinCode'.

So, the approach we follow in java is, create an 'Address' class with the following attributes:


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


and refer it in the 'Employee' class:


class Employee{
  int id;
  String name;
  Address address;
  ---Getters & Setters---
  }

Value Object

Now, just think for a moment! The 'Address' class comes to use only when it is referred by the 'Employee' class. In other words the 'Address' class does not have its own identity. Its purpose is only to serve the 'Employee' class. Such kind of objects (i.e. Address) are called as 'VALUE OBJECTS'.

Example :
Just imagine can a 'Wing' exist without a 'Bird'? The answer is no. So, if there is a 'Bird' class and it contains a reference of a 'Wing' object. The 'Wing' is a 'Value Object' and cannot exist on its own.

Component

The 'Value Objects'(i.e. the Address) can also be called as a 'Component'.

Why do we use a Component in Hibernate?

In the above case all the attributes of the 'Address' class(i.e. streetName, city, pinCode) is used inside the 'Employee' class. And yet we have two different classes in java.


But, what if we don't want two different tables in the database. Instead we want to club all the attributes of 'Address' and 'Employee' class and put it in the 'EMPLOYEE' table itself.


The 'EMPLOYEE' table would look something like the below structure:


ID NAME STREET_NAME CITY PIN_CODE

To achieve this, 'Component' comes into picture.

Let us follow the below steps for component mapping in Hibernate:

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


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

   <component name="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>
   </component>

  </class>
</hibernate-mapping>

The above lines are quite self explanatory.

<component name="address">

It means the 'Employee' class has a component called 'Address' and we are informing Hibernate the same using the 'component' tag.

And the 'Address' component has three attributes streetName, city and pinCode. Which we are mapping to the 'EMPLOYEE' table using the 'property' tag.

   <property name = "streetName" type = "string">
    <column name = "STREET_NAME">
   </property>

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

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

   Employee employee = new Employee();
   employee.setId(1);
   employee.setName("Joe");
   employee.setAddress(address);
   session.save(employee);

   session.getTransaction().commit();

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

So, what we are doing in the above case is, creating the 'Address' component and assigning values to it.

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

And since we are referencing 'Address' in the 'Employee' class, we have assigned the 'address' values to the 'Employee' class.

employee.setAddress(address);

And after saving the data using 'session.save(employee)', we get the data saved to the 'EMPLOYEE' table in the below structure.


ID NAME STREET_NAME CITY PIN_CODE
1 John Walls street Delhi 110012

And thats all we wanted. It is all because of the statement :

<component name="address">

in the mapping file which tells Hibernate that 'Address' class is a component and should be saved in a single row in the 'EMPLOYEE' table.