One-to-One Relationship in JPA

In this JPA (Java Persistence API) article, we will discuss different ways of achieving one-to-one mappings in JPA.
1 What is a One-to-One Relationship?
A one-to-one relationship in JPA is a type of association where each instance of an entity is directly linked to a single, unique instance of another entity. Formally, for every row in the first table, there is at most one corresponding row in the second table, and vice versa. This ensures that the relationship between the two entities is exclusive and bidirectional or unidirectional, depending on the mapping configuration.
To make it even clearer, consider a more naive and relatable example: think about a Person
and their Passport
. In most countries, each person can have only one valid passport at a time, and each passport is issued to only one person. This means there is a strict one-to-one relationship between the Person
and Passport
entities.
Here’s how this relationship might look in a real-world scenario:
- Person: Has attributes like
id
,name
,dateOfBirth
, etc. - Passport: Has attributes like
passportNumber
,issueDate
,expiryDate
, etc.
Each Person
is linked to exactly one Passport
, and each Passport
is linked to exactly one Person
. In a database, this can be represented by having a foreign key in the Passport
table that references the Person
table, or vice versa.
In summary, a one-to-one relationship in JPA is used to model scenarios where two entities are uniquely associated with each other, ensuring data consistency and integrity.
2 Achieving One-to-One Mapping in JPA
There are three different ways of achieving one-to-one mapping in JPA:
- Foreign Key Method In this approach, one entity contains a foreign key that references the primary key of the other entity.
- Shared Primary Key Method Here, both entities share the same primary key value, establishing a direct one-to-one correspondence.
- Join Table Method This method uses a separate join table to maintain the association between the two entities.
We will explore each of these methods in detail in the following sections. For better understanding, we will use the example of a Student
and their Marksheet
. In this scenario, each student has exactly one marksheet, and each marksheet belongs to exactly one student. This forms a classic one-to-one relationship, where the Student
entity is uniquely associated with the Marksheet
entity. Throughout the following sections, we will demonstrate how to implement this relationship using different mapping strategies in JPA.
2.1 Foreign Key Method
This method involves using a foreign key in one table that references the primary key in another table.
In our example, the student
table will have a column named marksheet_id
, which acts as a foreign key referencing the id
column in the mark_sheet
table. The mark_sheet
table itself contains columns such as id
, english
, and physics
to store the marks for each subject.
![]() |
![]() |
---|---|
Student Table | Marksheet Table |
Here is how you can implement the one-to-one relationship using the Foreign Key Method in JPA:
@Data
@Entity
public class MarkSheet {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private Integer physics;
private Integer english;
@OneToOne(mappedBy = "markSheet")
private Student student;
}
@Getter
@Setter
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "marksheet_id", referencedColumnName = "id")
private MarkSheet markSheet;
}
In this example:
- The
Student
entity has amarkSheet
field annotated with@OneToOne
and@JoinColumn
, indicating that themarksheet_id
column in thestudent
table is a foreign key referencing theid
column in themark_sheet
table. - The
MarkSheet
entity also uses the@OneToOne
annotation, with themappedBy
attribute to indicate that the relationship is managed by themarkSheet
field in theStudent
entity. - This setup creates a bidirectional relationship, meaning both entities (
Student
andMarkSheet
) are aware of each other and can access each other’s data directly through their respective fields. In a bidirectional one-to-one relationship, you can navigate fromStudent
toMarkSheet
and also fromMarkSheet
toStudent
, providing flexibility when querying or manipulating the associated entities.
This setup ensures that each student is associated with exactly one marksheet, and each marksheet belongs to exactly one student.
2.2 Shared Primary Key Method
In the Shared Primary Key Method, both entities use the same primary key value to establish a one-to-one relationship. This means the primary key of one entity is also a foreign key referencing the primary key of the other entity. This approach tightly couples the lifecycle of the two entities, ensuring that the existence of one directly depends on the other.
In our example, instead of creating an id
primary key column in the mark_sheet
table, we are using the primary key column (student_id
) which corresponds to the id
field in the student
table. It is illustrated below:
![]() |
![]() |
---|---|
Student Table | Marksheet Table |
Here is how you can implement the shared primary key one-to-one relationship in JPA:
@Getter
@Setter
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
@OneToOne(mappedBy = "student", cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private MarkSheet markSheet;
}
@Data
@Entity
public class MarkSheet {
@Id
@Column(name = "student_id")
private Integer id;
private Integer physics;
private Integer english;
@OneToOne
@JoinColumn(name = "student_id")
@MapsId
private Student student;
}
Here, we have used @PrimaryKeyJoinColumn
which indicates that the primary key of the student entity is used as a foreign key value for the associated mark sheet entity, which acts as a primary key for the mark sheet entity. You can see the @GeneratedValue
removed because it takes its value from the student id column. @MapsId
indicates that the primary key values will be copied from Student entity.
2.3 Join Table Method
There can be a scenario where a student may not have any mark sheet. If done with previous method, there will be null
values as shown in the figure.
![]() |
![]() |
---|---|
Student Table | Marksheet Table |
As there is no marksheet associated with John
, so it has a null
value in marksheet_id
.
Note: In a one-to-one mapping scenario, the Join Table Method establishes the relationship between two entities by introducing a third table, called a join table or associative table. This join table contains foreign keys referencing the primary keys of both related tables, ensuring a unique association between each pair of entities.
Generally, a join table is associated with many-to-many relationships, but using a join table in this case can help eliminate null values.
![]() |
![]() |
![]() |
---|---|---|
Student Table | Marksheet Table | MarksheetStudent Join Table |
Whenever there is a relation established between student
and marksheet
there is entry in student_marksheet
table with their respective primary keys
mapped.
Here is how you can implement the one-to-one relationship using the Join Table Method in JPA:
@Data
@Entity
public class MarkSheet {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private Integer physics;
private Integer english;
@OneToOne(mappedBy = "markSheet")
private Student student;
}
@Getter
@Setter
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
@OneToOne
@JoinTable(
name = "student_mark_sheet",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "marksheet_id")
)
private MarkSheet markSheet;
}
The @JoinTable
annotation instructs Hibernate to use a separate join table (student_mark_sheet
) to maintain the one-to-one relationship between Student
and MarkSheet
. This approach helps avoid null values in either table and keeps the association flexible.
Conclusion
A one-to-one relationship in JPA can be implemented using several strategies, each with its own advantages and trade-offs. The Foreign Key Method is straightforward and commonly used, the Shared Primary Key Method tightly couples the entities, and the Join Table Method offers flexibility and helps avoid null values. Choosing the right approach depends on your application’s requirements and the specific use case. Understanding these mapping techniques will help you design robust and efficient data models in your JPA-based applications.
Further Reading
If you want to dive deeper into one-to-one relationships in JPA, here are some excellent resources: