In this method, we will use a third table that contains the relationship between the employee and detail tables. In other words, the third table will hold a primary key value of both tables to represent a relationship between them.
Use the following script to create the tables and classes. Here, we use Employee
and EmployeeDetail
to show a one-to-one mapping using a common join table:
Use the following script to create the tables if you are not using hbm2dll=create|update
:
Use the following script to create the detail
table:
CREATE TABLE `detail` ( `detail_id` bigint(20) NOT NULL AUTO_INCREMENT, `city` varchar(255) DEFAULT NULL, PRIMARY KEY (`detail_id`) );
Use the following script to create the employee
table:
CREATE TABLE `employee` ( `employee_id` BIGINT(20) NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) DEFAULT NULL, PRIMARY KEY (`employee_id`) );
Use the following script to create the employee_detail
table:
CREATE TABLE `employee_detail` ( `detail_id` BIGINT(20) DEFAULT NULL, `employee_id` BIGINT(20) NOT NULL, PRIMARY KEY (`employee_id`), KEY `FK_DETAIL_ID` (`detail_id`), KEY `FK_EMPLOYEE_ID` (`employee_id`), CONSTRAINT `FK_EMPLOYEE_ID` FOREIGN KEY (`employee_id`) REFERENCES `employee` (`employee_id`), CONSTRAINT `FK_DETAIL_ID` FOREIGN KEY (`detail_id`) REFERENCES `detail` (`detail_id`) );
Use the following code to create the classes:
Source file: Employee.java
@Entity @Table(name = "employee") public class Employee { @Id @GeneratedValue @Column(name = "employee_id") private long id; @Column(name = "name") private String name; @OneToOne(cascade = CascadeType.ALL) @JoinTable( name="employee_detail" , joinColumns=@JoinColumn(name="employee_id") , inverseJoinColumns=@JoinColumn(name="detail_id") ) private Detail employeeDetail; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Detail getEmployeeDetail() { return employeeDetail; } public void setEmployeeDetail(Detail employeeDetail) { this.employeeDetail = employeeDetail; } @Override public String toString() { return "Employee" +" Id: " + this.id +" Name: " + this.name +" Employee Detail " + " Id: " + this.employeeDetail.getId() + " City: " + this.employeeDetail.getCity(); } }
@Entity @Table(name = "detail") public class Detail { @Id @GeneratedValue @Column(name = "detail_id") private long id; @Column(name = "city") private String city; @OneToOne(cascade = CascadeType.ALL) @JoinTable( name="employee_detail" , joinColumns=@JoinColumn(name="detail_id") , inverseJoinColumns=@JoinColumn(name="employee_id") ) private Employee employee; public Employee getEmployee() { return employee; } public void setEmployee(Employee employee) { this.employee = employee; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public long getId() { return id; } public void setId(long id) { this.id = id; } @Override public String toString() { return "Employee Detail" +" Id: " + this.id +" City: " + this.city +" Employee " + " Id: " + this.employee.getId() + " Name: " + this.employee.getName(); } }
In this section, we will take a look at how to insert a record step by step.
Using the following code, we will insert an Employee
record with a Detail
object:
Detail detail = new Detail(); detail.setCity("AHM"); Employee employee = new Employee(); employee.setName("vishal"); employee.setEmployeeDetail(detail); Transaction transaction = session.getTransaction(); transaction.begin(); session.save(employee); transaction.commit();
Hibernate: insert into detail (city) values (?) Hibernate: insert into employee (name) values (?) Hibernate: insert into employee_detail (detail_id, employee_id) values (?,?)
Hibernate saves one record in the detail
table and one in the employee
table and then inserts a record in to the third table, employee_detail
, using the primary key column value of the detail
and employee
tables.
From the output, it's clear how this method works. The code is the same as in the other methods of configuring a one-to-one relationship, but here, hibernate reacts differently. Here, the first two statements of output insert the records in to the detail
and employee
tables respectively, and the third statement inserts the mapping record in to the third table, employee_detail
, using the primary key column value of both the tables.
Let's take a look at an option used in the previous code in detail:
@JoinTable
: This annotation, written on the Employee
class, contains the name="employee_detail"
attribute and shows that a new intermediate table is created with the name "employee_detail"
joinColumns=@JoinColumn(name="employee_id")
: This shows that a reference column is created in employee_detail
with the name "employee_id"
, which is the primary key of the employee
tableinverseJoinColumns=@JoinColumn(name="detail_id")
: This shows that a reference column is created in the employee_detail
table with the name "detail_id"
, which is the primary key of the detail tableUltimately, the third table, employee_detail
, is created with two columns: one is "employee_id
" and the other is "detail_id
".