One-to-One mapping in Hibernate
In Hibernate One-to-One mapping can be done in 2 ways:
- Primary key association:
- Foreign key association.
This article describes how a Primary key One-to-one association can be done.
Consider a Customer and address entities. Each customer will have one address. And an address is associated with one customer. To make this relationship work in database customer and address will have same Id(primary key). Mapping this kind of relationship in Hibernate is called primary key One-to-One association. Doing so will help you saving, updating, deleting related entities easy.
Define following 2 tables in mysql database.
create table customer(
customer_id int(11) not null auto_increment,
name varchar(50) not null,
email_id varchar(100),
contact_no varchar(20),
primary key(customer_id));create table address(
address_id int(11) not null,
address_line1 varchar(100) not null,
address_line2 varchar(100),
city varchar(50) not null,
state varchar(50) not null,
pincode int(10) not null,
primary key(address_id),
foreign key(address_id) references customer(customer_id));
Here both customer and address share same primary key. Address_id is primary key and also a foreign key. Any new address should belong to a some customer. Customet ID will be an autogenerated sequence in database. But Address ID shuld be copied from customer table.
Now lets define the entities:
Customer.java Address.java
(you can download full code at the end of the article)
Customer.java bean has the following fields and their getter and setter methods:
long customerId;
String name;
String emailAddress;
String contactNo;
Address address;
And Address.java bean has follow following fields and their getter and setter methods:
long addressId;
String addressLine1;
String addressLine2;
String city;
String state;
Integer pincode;
Customer customer;
In One-to-One primary key mapping, we need to relate both the entities bidirectional.We need to have address property in customer and vice versa.
Lets define the hibernate mapping files:
customer.hbm.xml file will look like below:
<?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=”entities.Customer” table=”CUSTOMER”>
<id name=”customerId” type=”long” column=”customer_id” >
<generator/>
</id>
<property name=”name”>
<column name=”NAME” />
</property>
<property name=”emailAddress”>
<column name=”email_id” />
</property>
<property name=”contactNo”>
<column name=”contact_no” />
</property>
<one-to-one name=”address”
cascade=”all”
>
</one-to-one>
</class>
</hibernate-mapping>
Important part is the one-to-one mapping. Name should point to the Address type variable defined in Customer entity.
We have cascade =“all”. This means both the entities are related in all the operations.Adding / updating and deleting Customer will also do same on related address entity.
address.hbm.xml file will look like below:
<?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=”entities.Address” table=”ADDRESS”>
<id name=”addressId” type=”long” column=”address_id” >
<generator>
<param name=”property”>customer</param>
</generator></id>
<property name=”addressLine1″>
<column name=”address_line1″ />
</property>
<property name=”addressLine2″>
<column name=”address_line2″ />
</property>
<property name=”city”>
<column name=”city” />
</property>
<property name=”state”>
<column name=”state” />
</property>
<property name=”pincode”>
<column name=”pincode” />
</property>
<one-to-one name=”customer”
constrained=”true” />
</class>
</hibernate-mapping>
In this mapping file we have to ensure 2 things:
- Address table do not have any ID generation strategy. It has to get id from customer table.
- The Address ID is a foreign key which should be specified to hibernate.
This is to ensure the order of insert/delete and update statements, which hibernate would perform on these two tables.
<id name=”addressId” type=”long” column=”address_id” >
<generator>
<param name=”property”>customer</param>
</generator>
</id>
Is to ensure that the addresseId gets a value of customerId we use special id generation strategy called “foreign”.
To specify the foreign key constraint on addressId, we have set constrained=”true” like below in address.hbm.xml file
<one-to-one name=”customer”constrained=“true” />
Now the mapping part is over. We can test it using following client code:
// saving the Customer and Address data
Customer customer = new Customer();
customer.setName(“Surya”);
customer.setEmailAddress(“surya@gmail.com“);
customer.setContactNo(“91-932686876″);
Address address = new Address();
address.setAddressLine1(“xxx-street, near Surya Complex”);
address.setCity(“Pune”);
address.setState(“Maharashtra”);
address.setPincode(11111);
customer.setAddress(address);
address.setCustomer(customer);
session.save(customer);
//Fetch all the customers
Query query = session.createQuery(“from Customer customer”);
for(Iterator it=query.iterate();it.hasNext();){
Customer customer1 = (Customer) it.next();
Address address1 = customer1.getAddress();
System.out.println(“customer ID: ” + customer1.getCustomerId());
System.out.println(“Name: ” + customer1.getName());
System.out.println(“address: ” + address1.getAddressLine1());
System.out.println(address1.getAddressLine2());
System.out.println(address1.getCity());
System.out.println(address1.getState());
System.out.println(address1.getPincode());
}// delete a customer – also delete address
Query query = session.createQuery(“from Customer customer where customer.customerId = :cust”).setLong(“cust”, 3);
Customer customer2 = (Customer) query.uniqueResult();
session.delete(customer2);// delete only Address
Query query = session.createQuery(“from Customer customer where customer.customerId = :cust”).setLong(“cust”, 1);
Customer customer2 = (Customer) query.uniqueResult();
Address address2 = customer2.getAddress();
customer2.setAddress(null);
address2.setCustomer(null);
session.delete(address2);
You can download full code from here.

