Hibernate One to One Mapping Example(Annotation Based)

By Dhiraj Ray, 27 February,2017  

This post is continuation to my last post - hibernate annotations. Here we will be discussing about hibernate one to one mapping in detail with an example. We will take a look into both unidirectional and bidirectional one to one realationship and even discuss about different optional annotations used in one to one mapping such as mappedBy, CascadeType, FetchTye and others.

What is One to One Mapping

One to One relation specifies that an entity(A) is associated to only a single instance of another entity(B). From database perspective, you can assume that if table A has a one to one mapping with table B, then each row of Table B will have a foreign key column which refers to a primary key of Table A.

Let us represent this in a SQL query. Following is the table structure we will be using for this example.

hibernate-one-to-one-mapping-example
CREATE TABLE EMPLOYEES ( RECORD_ID INT NOT NULL AUTO_INCREMENT, AGE INT, NAME VARCHAR(255), PRIMARY KEY (RECORD_ID) ) ENGINE=InnoDB; CREATE TABLE PHONES ( RECORD_ID INT NOT NULL AUTO_INCREMENT, NAME VARCHAR(255), EMP_ID INT, PRIMARY KEY (RECORD_ID) ) ENGINE=InnoDB; ALTER TABLE phones ADD CONSTRAINT FK_28498m2ap6ybm5xn8tce6iwmh FOREIGN KEY (EMP_ID) REFERENCES EMPLOYEES (RECORD_ID)

From above sql its clear that table PHONES has a foreign key column - EMP_ID that references to primary key of table EMPLOYEES and there is one to one mapping in between them meaning one row of table PHONES is refering to single row of table EMPLOYEES via foreign key EMP_ID present in table PHONES.

Environment Setup

1. JDK 7 2. Hibernate 4 3. Intellij Idea/ eclipse 4. MySql 5. Maven

Project Structure

We have 2 model classes - Employee.java and Phone.java that has one to one relationship. We have Application.java that has a main method which will be used to start the application. Here the hibernate.cfg.xml file is under hibernate directory.

Maven Dependencies

Following are the maven dependencies required to include in pom.xml to get started.

pom.xml
<dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.3.11.Final</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.18.0-GA</version> </dependency> </dependencies>

Defining hibernate.cfg.xml

<hibernate-configuration> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost/test</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <property name="hibernate.hbm2ddl.auto">update</property> <property name="show_sql">false</property> <mapping class="com.devglan.model.Employee"/> <mapping class="com.devglan.model.Phone"/> </session-factory> </hibernate-configuration>

Defining hibernate Entities for One to One Mapping

From above sql queries we confirmed that table EMPLOYEES and PHONES have one to one mapping. Now let us define it in hibernate first and then we will discuss different about different annotations involved.

Employee.java
package com.devglan.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "EMPLOYEES") public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "RECORD_ID") private Integer id; @Column(name = "NAME") private String name; @Column(name="AGE") private Integer age; @OneToOne(mappedBy = "emp") private Phone phone; public Employee() { } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Phone getPhone() { return phone; } public void setPhone(Phone phone) { this.phone = phone; } }

You can see the annotation @OneToOne that adds metadata as Employee class has one to one mapping with Phone.java as thi annotation is defined above the Phone class variable declaration. We ill be discussing about other attributes in coming section. Now let us define Phone.java

Phone.java
package com.devglan.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.Table; @Entity @Table(name = "PHONES") public class Phone { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "RECORD_ID") privateInteger id; @Column(name = "NAME") private String no; @OneToOne @JoinColumn(name = "EMP_ID") private Employee emp; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getNo() { return no; } public void setNo(String no) { this.no = no; } public Employee getEmp() { return emp; } public void setEmp(Employee emp) { this.emp = emp; } }

In Phone.java you can see @JoinColumn annotation that adds metadata about foeign key column. Above entity configurations are for unidirectional mapping relations as we are using mappedBy attribute.

Optional Attributes used in One TO One Mapping

Apart from annotations used in the entity class, there are other optional annotations that we can use during hibernate one to one mapping.

CascadeType - It defines operaions that must be cascaded. By default, no operation is cascaded. For different types of cascading follow Hibernate Docs

mappedBy - It defines the field which owns the relationship. This element is specified on the now owning side of the association. This is only required when relationship is unidirectional. Owning side is the entity having foreign column.

Fetch - It defines whether mapped entity should be lazily or eagerly initialised.

Example Operations in One to One Mapping

Now let us see how to create entries of mapped entities in database using hibernate.

Application.java
package com.devglan.model; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; public class Application { public static void main(String[] args) { createEmployee(); } public static SessionFactory getSessionFactory() { Configuration configuration = new Configuration().configure(); StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder() .applySettings(configuration.getProperties()); SessionFactory sessionFactory = configuration .buildSessionFactory(builder.build()); return sessionFactory; } public static void createEmployee() { System.out.println("****************Creating Employee*************"); Employee emp = new Employee("Jhn Doe", 44); Phone ph = new Phone(); ph.setNo("12345678"); ph.setEmp(emp); emp.setPhone(ph); Session session = getSessionFactory().openSession(); session.beginTransaction(); session.save(emp); session.getTransaction().commit(); session.close(); System.out.println("Employee Created Successfully" + emp.toString()); } }

Once, you run the Application.java as a java application, you can see entries created in table EMPLOYESS and PHONES with foreign key populated in table PHONES.

I hope this article served you whatever you were looking for. If you have anything that you want to add or share then please share it below in the comment section.

Download the source

References: Hibernate Docs One to One Docs

Suggest more topics in suggestion section or write your own article and share with your colleagues.

Is this page helpful to you? Please give us your feedback below. We would love to hear your thoughts on these articles, it will help us improve further our learning process.

Further Reading: