Hibernate - Bag Mapping
A Bag is similar to a Set and a List except it does not contain duplicates and it is not ordered.
A 'bag' in java can be represented by a 'Collection' interface, initialized by an 'ArrayList'.
So, let us modify our 'Employee' class accordingly.
class Employee{
int id;
String name;
Collection<Address> addressBag = new ArrayList<Address>();
---Getters & Setters---
}
We have initialized the 'Collection' with an 'ArrayList' to represent a 'bag' in java.
Note : Now, since the concrete class of the 'Collection' is an 'ArrayList', we will be following the same steps we have followed for 'List' mapping in our main class.
So, 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 'Bag'.
<?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 = "EMP_ID">
</id>
<property name = "name" type = "string">
<column name = "NAME">
</property>
<bag name="addressBag" table="ADDRESS">
<key column="ID"/>
<collection-id type="int" column="BAG_COUNTER">
<generator class="increment">
</collection-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>
</bag>
</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 'Collection' of java to achieve that.
<bag name="addressBag" 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">
The next line is specific to 'Collection' or 'bag'. Since, we have used 'ArrayList' for initializing the 'Collection', we will be generating a new column 'BAG_COUNTER' which will be keeping a track of the data inserted.
<collection-id type="int" column="BAG_COUNTER">
<generator class="increment">
</collection-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();
Collection <Address> addressBag = new ArrayList <Address>();
Address localAddress = new Address();
localAddress.setStreetName("Walls Street");
localAddress.setCity("Delhi");
localAddress.setPinCode("110012");
addressBag.add(localAddress);
Address permanentAddress = new Address();
permanentAddress.setStreetName("Murugeshpalya");
permanentAddress.setCity("Bangalore");
permanentAddress.setPinCode("560019");
addressBag.add(permanentAddress);
Employee employee = new Employee();
employee.setId(1);
employee.setName("Joe");
employee.setAddressBag(addressBag);
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 'Collection'. We have created a 'Collection' type object initialized by an 'ArrayList'.
Collection <Address> addressBag = new ArrayList <Address>();
to store the 'localAddress'
addressList.add(localAddress)
addressList.add(permanentAddress);
And finally we need to add the Collection 'addressBag' to the 'Employee' object.
employee.setAddressBag(addressBag);
EMPLOYEE
ADDRESS
BAG_COUNTER |
ID |
STREET_NAME |
CITY |
PIN_CODE |
1 |
1 |
Walls street |
Delhi |
110012 |
2 |
1 |
Murugeshpalya |
Bangalore |
560019 |
If you see the above table, a new column 'BAG_COUNTER' is created in the 'ADDRESS' table which keeps track of the bag insertion.