There are 3 ways to map One-To-Many and Many-To-One relationship in JPA and Hibernate by using @OneToMany and @ManyToOne, including
Bidirectional mapping with @OneToMany and @ManyToOne
Unidirectional mapping with @ManyToOne
Unidirectional mapping with @OneToMany
This guide will show you how to map along with the pros and cons of each approach
Consider the relationship between the library and books. One library may have many books, one book can only be managed by one library
Bidirectional mapping with @OneToMany and @ManyToOne
@OneToMany would be placed on a collection association of an entity (or the One side) with the mappedBy
attribute pointing to the relationship owner
@Entity
public class Library {
...
@OneToMany(mappedBy = "library", cascade = CascadeType.ALL)
private Set<Book> books = new HashSet<>();
...
}
@ManyToOne would be placed on the single item association of an entity (or the relationship owner; the table with a foreign key column in the underlying database)
@Entity
public class Book {
...
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "library_id")
private Library library;
...
}
@JoinColumn specifies the foreign key column. It is optional for bidirectional mapping, default name to the underscore string join of the association field name and its primary key column name
On the opposite, the mappedBy
attribute on @OneToMany is required to specify for bidirectional mapping. If mappedBy
is absent, JPA and Hibernate will create a redundant join table library_books
+------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+-------+
| library_id | int(11) | NO | PRI | NULL | |
| books_id | int(11) | NO | PRI | NULL | |
+------------+---------+------+-----+---------+-------+
Pros and cons
Both entities of the relationship can quickly access and cascade CRUD operations to each other
@OneToMany can cause a performance issue on a large child collection
Hands-on tutorials
Spring Boot JPA and Hibernate One To Many Bidirectional Mapping with HSQL
Spring Boot JPA and Hibernate Bidirectional One To Many REST API with MySQL
Unidirectional mapping with @ManyToOne
@ManyToOne would be placed on a single item association of an entity (or on the table with a foreign key column in the underlying database). There is no child collection association mapping on the parent entity
@Entity
public class Book {
...
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "library_id")
private Library library;
...
}
@JoinColumn specifies the foreign key column. It is optional for unidirectional @ManyToOne mapping, default name to the underscore string join of the association field name and its primary key column name
Pros and cons
Avoid the potential performance issue of @OneToMany
The parent entity can not navigate or cascade CRUD operations to the child collection. However, you can do it manually via JPQL query
Hands-on tutorials
Unidirectional mapping with @OneToMany
@OneToMany would be placed on a child collection of an entity (or the One side) with @JoinColumn and without mappedBy
We don't need to specify the mappedBy attribute on unidirectional @OneToMany as there is no parent association mapping on the child entity
@Entity
public class Library {
...
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "library_id")
private Set<Book> books = new HashSet<>();
...
}
@JoinColumn is required to specify the foreign key column for unidirectional @OneToMany. If @JoinColumn is absent, JPA and Hibernate will create a redundant join table library_books
+------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+-------+
| library_id | int(11) | NO | PRI | NULL | |
| books_id | int(11) | NO | PRI | NULL | |
+------------+---------+------+-----+---------+-------+
Pros and cons
The parent entity can quickly access and cascade CRUD operations to child collection
The child entity cannot navigate the parent entity
@OneToMany can cause a performance issue on a large child collection
In this article, we had a quick look at various ways to map One to Many and Many to One relationship in JPA and Hibernate along with the notes on their pros and cons