Spring Boot JPA One to One

Lets learn how to use Spring Boot JPA to implement One to One relationship.

You can model One-to-One relationships between entities using the @OneToOne annotation. In a one-to-one relationship, each record in one table is associated with one and only one record in another table.

Bidirectional One-to-One Relationship

We can have two entities Person and Address. A person can have only one address and an address belongs to only one person.

Person entity:

1
2
3
4
5
6
7
8
9
10
11
12
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;

@OneToOne(mappedBy = "person")
private Address address;

// getters and setters
}

The @OneToOne annotation is used to create a one-to-one relationship between the Person and Address entities. The mappedBy attribute is used to specify the property in the Address entity that owns the relationship.

Address entity:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Entity
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String street;
private String city;

@OneToOne
@JoinColumn(name = "person_id")
private Person person;

// getters and setters
}

An address belongs to only one person. The @JoinColumn annotation is used to specify the foreign key column in the Address entity that refers to the primary key column in the Person entity.

Test the relationship by creating a Person and an Address and setting the address to the person.

1
2
3
4
5
6
7
8
9
10
11
Person person = new Person();
person.setName("Alice");

Address address = new Address();
address.setStreet("123 Main St");
address.setCity("Springfield");

person.setAddress(address);
address.setPerson(person);

personRepository.save(person);

Unidirectional One-to-One Relationship

It is also possible to create a unidirectional one-to-one relationship.

Person entity:

1
2
3
4
5
6
7
8
9
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;

// getters and setters
}

Address entity:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Entity
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String street;
private String city;

@OneToOne
@JoinColumn(name = "person_id")
private Person person;

// getters and setters
}

Test:

1
2
3
4
5
6
7
8
9
10
Person person = new Person();
person.setName("Alice");

Address address = new Address();
address.setStreet("123 Main St");
address.setCity("Springfield");

address.setPerson(person);

addressRepository.save(address);

@MapsId Example

In some cases, you may want the primary key of the child entity to be the same as the primary key of the parent entity. You can achieve this using the @MapsId annotation. @MapsId can be used in a One-to-One relationship or a Many-to-One relationship.

1
2
3
4
5
6
7
8
9
10
11
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;

@OneToOne(mappedBy = "person")
private Address address;
// getters and setters
}
1
2
3
4
5
6
7
8
9
10
11
12
13
@Entity
public class Address {
@Id
private Long id;

private String street;

@OneToOne
@MapsId
@JoinColumn(name = "person_id")
private Person person;
// getters and setters
}