5.1 Various forms of one-to-one communication

There is another interesting and rather specific case of a relationship between two Entity classes - a one-to-one relationship.

I call this case very specific, as it's more about Java objects than a database. In the database, there are only two options for the relationship between tables:

  • The table row contains a link to the id of another table.
  • The service table is used for many-to-many relationships.

In the case of Entity classes, there may be options that are described by several annotations:

  • @Embedded
  • One-sided OneToOne
  • Bilateral OneToOne
  • @MapsId

Below we will consider the most popular of them.

5.2 Embedded

By the way, we have already considered the simplest one-to-one@Embedded communication option - this is an annotation . In this case, we have two classes stored in the same table in the database.

Let's say we want to store the user's address in the UserAddress class :

class UserAddress {
   public String country;
   public String city;
   public String street;
   public String home;

Then we just need to add a field with this address to the User class :

class User {
   public Integer id;
   public UserAddress address;
   public Date createdDate;

Hibernate will do the rest: the data will be stored in one table, but when writing HQL queries, you will need to operate on class fields.

HQL query example:

select from User where address.city = 'Paris'

5.3 One-sided OneToOne

Imagine now the situation: we have a source table employee and a task that refers to employee. But we know for sure that a maximum of one task can be assigned to one user. Then we can use the annotation to describe this situation @OneToOne.


class EmployeeTask {
   public Integer id;
   public String description;
   @JoinColumn(name = "employee_id")
   public Employee employee;
   public Date deadline;

Hibernate will make sure that not only one task has one user, but also that one user has only one task. Otherwise, this case is practically no different from @ManyToOne.

5.4 Bilateral OneToOne

The previous option can be a little inconvenient, because often you want to assign an employee not only to a task, but also assign a task to an employee.

To do this, you can add the EmployeeTask field to the Employee class and give it the correct annotations.

class Employee {
   public Integer id;
   @OneToOne(cascade = CascadeType.ALL, mappedBy="employee")
   private EmployeeTask task;

Important!The employee table does not have a task_id field , instead the employee_id field of the task table is used to establish a relationship between tables .

Establishing a connection between objects looks like this:

Employee director = session.find(Employee.class, 4);
EmployeeTask task = session.find(EmployeeTask.class, 101);
task.employee = director;
director.task = task;

To remove the link, the links must also be removed from both objects:

Employee director = session.find(Employee.class, 4);
EmployeeTask task = director.task;
task.employee = null;
director.task = null;

Module 4. Working with databases, level 13, lesson 4