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)
addressSet.add(permanentAddress);
And finally we need to add the Set 'addressSet' to the 'Employee' object.
employee.setAddressSet(addressSet);
EMPLOYEE
ADDRESS
ID |
STREET_NAME |
CITY |
PIN_CODE |
1 |
Walls street |
Delhi |
110012 |
1 |
Murugeshpalya |
Bangalore |
560019 |