One-to-one mapping using a common join table

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.

Getting ready

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:

Creating the tables

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`)
);

Creating the classes

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();

  } 

}

Source file: Detail.java

@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();

  }
  
}

How to do it…

In this section, we will take a look at how to insert a record step by step.

Inserting a record

Using the following code, we will insert an Employee record with a Detail object:

Code

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();

Output

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.

How it works…

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 table
  • inverseJoinColumns=@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 table

Ultimately, the third table, employee_detail, is created with two columns: one is "employee_id" and the other is "detail_id".

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset