Hibernate One To Many Bidirectional Mapping Example
Let us see how to achieve, Bidirectional one to many mapping in hibernate…
Actually in normal one to many, the relation is from parent to child i mean if we do the operations on parent object will be automatically reflected at child objects too right…?
Similarly in many to one the relation is from child to parent object, hope you remembered this concept, if not so just go back and have a look once..
Bidirectional one to many >>>> Combination of these above 2
Let us see an example…
files required…
- Vendor.java [pojo]
- Customer.java [pojo]
- Vendor.hbm.xml
- Customer.hbm.xml
- hibernate.cfg.xml
- OurLogic.java [Our logic]
Vendor.java
123456789101112131415161718192021222324252627282930package str; import java.util.Set; public class Vendor { private int vendorId; private String vendorName; private Set children; public int getVendorId() { return vendorId; } public void setVendorId(int vendorId) { this.vendorId = vendorId; } public String getVendorName() { return vendorName; } public void setVendorName(String vendorName) { this.vendorName = vendorName; } public Set getChildren() { return children; } public void setChildren(Set children) { this.children = children; } }
Customer.java
1234567891011121314151617181920212223242526272829303132333435package str; public class Customer { private int customerId; private String customerName; private int forevenId; private Vendor parentObjets; public Vendor getParentObjets() { return parentObjets; } public void setParentObjets(Vendor parentObjets) { this.parentObjets = parentObjets; } public int getCustomerId() { return customerId; } public void setCustomerId(int customerId) { this.customerId = customerId; } public String getCustomerName() { return customerName; } public void setCustomerName(String customerName) { this.customerName = customerName; } public int getForevenId() { return forevenId; } public void setForevenId(int forevenId) { this.forevenId = forevenId; } }
Vendor.hbm.xml
1234567891011121314151617181920<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="str.Vendor" table="vendor"> <id name="vendorId" column="vendid" /> <property name="vendorName" column="vendname" length="10"/>
<set name="children" cascade="all" inverse="true">
<key column="forevenid" /> <one-to-many class="str.Customer" /> </set> </class> </hibernate-mapping>
Note:
- Here we are writing one new attribute inverse=”true” , means we are intimating to hibernate that we are doing Bi Directional operation
- But default value of inverse=”false“
Customer.hbm.xml
12345678910111213141516<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="str.Customer" table="customer"> <id name="customerId" column="custid" /> <property name="customerName" column="custname" length="10"/> <property name="forevenId" column="forevenid" insert="false" /> <many-to-one name="parentObjets" column="PrentsIds" cascade="all"/> </class> </hibernate-mapping>
hibernate.cfg.xml
123456789101112131415161718192021<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver </property> <property name="connection.url">jdbc:oracle:thin:@www.java4s.com:1521:XE</property> <property name="connection.username">system</property> <property name="connection.password">admin</property> <property name="dialect">org.hibernate.dialect.OracleDialect</property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">update</property> <mapping resource="Customer.hbm.xml"></mapping> <mapping resource="Vendor.hbm.xml"></mapping> </session-factory> </hibernate-configuration>
OurLogic.java
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869package str; import java.util.HashSet; import java.util.Set; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; public class OurLogic { public static void main(String args[]) { Configuration cfg = new Configuration(); cfg.configure("hibernate.cfg.xml"); SessionFactory factory = cfg.buildSessionFactory(); Session session = factory.openSession(); Vendor v =new Vendor(); v.setVendorId(101); v.setVendorName("java4s"); Customer c1=new Customer(); c1.setCustomerId(504); c1.setCustomerName("customer4"); Customer c2=new Customer(); c2.setCustomerId(505); c2.setCustomerName("customer5"); Customer c3=new Customer(); c3.setCustomerId(506); c3.setCustomerName("customer6");
// one-to-many
Set s=new HashSet(); s.add(c1); s.add(c2); s.add(c3); v.setChildren(s);
// many-to-one
c1.setParentObjets(v); c2.setParentObjets(v); c3.setParentObjets(v); Transaction tx = session.beginTransaction();
session.save(c1);
//session.save(v);
tx.commit(); session.close(); System.out.println("One To Many Bi-Directional is Done..!!"); factory.close(); } }
Notes:
- See line number 59,60 actually we can save any object either parent or child [ as it is Bi directional inverse will take automatically ], but in our application i saved child object.
- In this above logic, even though we are saving a single child object, but in the database all child objects are inserted at the time of executing the code, the reason being… the time of saving c1 object, first its parent object v will be inserted, as the parent object v has 3 child objects so hibernate will save all the 3 child objects in the database
- In Vendor.hbm.xml, we have included an attribute in the set element called inverse, this attribute informs the hibernate that the relation ship is Bi Directional
- If we write inverse = “false” then hibernate understands that relationship as unidirectional and generates additional update operations on the database, so in order to reduce the internal operations, we need to include inverse=”true“
- remember, default value of inverse =”false”
- If we make inverse =”true” the performance will be increased, i guess ?
post a comment