Hibernate BiDirectional Mapping in Detail

Hibernate bidirectional mapping is the most common mapping. This is the typical parent child relationship scenario, where the children can be retrieved using parent, and the parent can be retrieved using a child. In short, these relations can be traverse in either direction. Hibernate achieves this using a property ‘inverse=true/false’. This property can be applied in all mapping possibilities i.e. Many-to-one, one-to-many and one-to-one. Sometimes, it will be as simple as adding this property to the link element. Let us take an example of this mapping. We continue with same customer and address example with Many – to – one in parent to child direction, and one-to-many in reverse direction.

Database Changes for Hibernate Bidirectional Mapping:


Database remains same as the Unidirectional many-to-one example.

TAB_CUSTOMER
	CUSTOMER_ID - Number - Not NULL Primary Key
	ADDRESS_ID - Number - Not NULL Foreign Key from Tab_Address table

TAB_ADDRESS
	ADDRESS_ID - Number - Not NULL Primary Key

Hibernate Bidirectional Mapping:


Let us reflect this bidirectional business in our mapping.
<class name=”Customer” table=”TAB_CUSTOMER”>
<id name=”id” column=”CUSTOMER_ID”> <generator class=”native”/> </id>
<many-to-one name=”address” column=”ADDRESS_ID” not-null=”true”/>
</class>
<class name=”Address” table=”TAB_ADDRESS”>
<id name=”id” column=”ADDRESS_ID”> <generator class=”native”/> </id>
<Set name=”customers” inverse=”true”>
<key column=”ADDRESS_ID” not-null=”true”/>
<one-to-many class=”Customer”/>
</Set>
</class>

Java:
Here, we will have Customer class containing an attribute to hold address; also Address class will hold customers. Simple reason, if you retrieve customer object, then also you will have complete information of addresses of that customer. Even if you start data retrieval using address object, you will get information of customers which have this address.

public class Customer {
    private Long id;
    private Address address;
    // getter/setter for id & address fields
}     

  public class Address {
          private Long id;
         private Set customers;
 // getter/setter for id and customers fields
}

Extension to One-to-One Relation:
If we want to extend the bidirectional relation to one-to-one association, then it is easier than above example. Instead of multiple objects/collection of customers in Address class, we will have only one object. You will definitely need the unique constraint on the foreign key column.

Extension to Join table:
Just to give brief introduction of this hibernate bidirectional mapping style, here we link the two classes using ‘join’ tag. Take a look at the many to many unidirectional association example. We used an intermediate table to link customer and address entities. Now we join our customer table to the intermediate customeraddress table, and also address table to the customeraddress table. Same thing reflected in the mapping and inverse can be added on any side of the association. The mapping of this scenario will be like following.

<class name=”Customer” table=”TAB_CUSTOMER”>
<id name=”id” column=”CUSTOMER_ID”> <generator class=”native”/> </id>
<join table=”TAB_CUSTOMERADDRESS” optional=”true”>
<key column=”CUSTOMER_ID” unique=”true”/>
<many-to-one name=”address” column=”ADDRESS_ID” not-null=”true” unique=”true”/>
</join>
</class>
<class name=”Address” table=”TAB_ADDRESS”>
<id name=”id” column=”ADDRESS_ID”> <generator class=”native”/> </id>
<join table=”TAB_CUSTOMERADDRESS” optional=”true” inverse=”true”>
<key column=”ADDRESS_ID” unique=”true”/>
<many-to-one name=”customer” column=”CUSTOMER_ID” not-null=”true” unique=”true”/>
</join>
</class>

Just to add, in both Java classes, we need attributes to hold instance of the other class.

1 Comment

Leave a Reply

Your email address will not be published.


*