Introduction
When designing a relational database in Java, one of the most essential relationships you’ll come across is Many-to-One mapping. It allows multiple entities to be linked to a single parent entity, making data organization more efficient.
In this blog, we’ll break it down so that you can:
- Understand what Many-to-One mapping is.
- Implement it using Spring Boot, JPA, and Hibernate.
- Explore real-world use cases for this relationship.
Let’s dive in!
What is Many-to-One Mapping?
A Many-to-One relationship means that many child entities are associated with a single parent entity.
Real-World Examples:
- Many employees belong to one department.
- Many orders are placed by one customer.
- Many books are written by one author.
In database terms, this means that the child table contains a foreign key referencing the primary key of the parent table.
JPA makes it easy to define this relationship using the @ManyToOne
annotation. Let’s see how to implement it!
Implementing Many-to-One Mapping in Spring Boot
1️⃣ Many-to-One Using a Foreign Key (Recommended )
The most common approach is to have a foreign key in the child table pointing to the parent table.
Step 1: Create the Department
Entity (Parent)
<span>import</span> <span>jakarta.persistence.*</span><span>;</span><span>import</span> <span>java.util.List</span><span>;</span><span>@Entity</span><span>public</span> <span>class</span> <span>Department</span> <span>{</span><span>@Id</span><span>@GeneratedValue</span><span>(</span><span>strategy</span> <span>=</span> <span>GenerationType</span><span>.</span><span>IDENTITY</span><span>)</span><span>private</span> <span>Long</span> <span>id</span><span>;</span><span>private</span> <span>String</span> <span>name</span><span>;</span><span>@OneToMany</span><span>(</span><span>mappedBy</span> <span>=</span> <span>"department"</span><span>,</span> <span>cascade</span> <span>=</span> <span>CascadeType</span><span>.</span><span>ALL</span><span>)</span><span>private</span> <span>List</span><span><</span><span>Employee</span><span>></span> <span>employees</span><span>;</span><span>// Getters and Setters</span><span>}</span><span>import</span> <span>jakarta.persistence.*</span><span>;</span> <span>import</span> <span>java.util.List</span><span>;</span> <span>@Entity</span> <span>public</span> <span>class</span> <span>Department</span> <span>{</span> <span>@Id</span> <span>@GeneratedValue</span><span>(</span><span>strategy</span> <span>=</span> <span>GenerationType</span><span>.</span><span>IDENTITY</span><span>)</span> <span>private</span> <span>Long</span> <span>id</span><span>;</span> <span>private</span> <span>String</span> <span>name</span><span>;</span> <span>@OneToMany</span><span>(</span><span>mappedBy</span> <span>=</span> <span>"department"</span><span>,</span> <span>cascade</span> <span>=</span> <span>CascadeType</span><span>.</span><span>ALL</span><span>)</span> <span>private</span> <span>List</span><span><</span><span>Employee</span><span>></span> <span>employees</span><span>;</span> <span>// Getters and Setters</span> <span>}</span>import jakarta.persistence.*; import java.util.List; @Entity public class Department { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @OneToMany(mappedBy = "department", cascade = CascadeType.ALL) private List<Employee> employees; // Getters and Setters }
Enter fullscreen mode Exit fullscreen mode
Step 2: Create the Employee
Entity (Child)
<span>import</span> <span>jakarta.persistence.*</span><span>;</span><span>@Entity</span><span>public</span> <span>class</span> <span>Employee</span> <span>{</span><span>@Id</span><span>@GeneratedValue</span><span>(</span><span>strategy</span> <span>=</span> <span>GenerationType</span><span>.</span><span>IDENTITY</span><span>)</span><span>private</span> <span>Long</span> <span>id</span><span>;</span><span>private</span> <span>String</span> <span>name</span><span>;</span><span>@ManyToOne</span><span>@JoinColumn</span><span>(</span><span>name</span> <span>=</span> <span>"department_id"</span><span>,</span> <span>nullable</span> <span>=</span> <span>false</span><span>)</span><span>private</span> <span>Department</span> <span>department</span><span>;</span><span>// Getters and Setters</span><span>}</span><span>import</span> <span>jakarta.persistence.*</span><span>;</span> <span>@Entity</span> <span>public</span> <span>class</span> <span>Employee</span> <span>{</span> <span>@Id</span> <span>@GeneratedValue</span><span>(</span><span>strategy</span> <span>=</span> <span>GenerationType</span><span>.</span><span>IDENTITY</span><span>)</span> <span>private</span> <span>Long</span> <span>id</span><span>;</span> <span>private</span> <span>String</span> <span>name</span><span>;</span> <span>@ManyToOne</span> <span>@JoinColumn</span><span>(</span><span>name</span> <span>=</span> <span>"department_id"</span><span>,</span> <span>nullable</span> <span>=</span> <span>false</span><span>)</span> <span>private</span> <span>Department</span> <span>department</span><span>;</span> <span>// Getters and Setters</span> <span>}</span>import jakarta.persistence.*; @Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @ManyToOne @JoinColumn(name = "department_id", nullable = false) private Department department; // Getters and Setters }
Enter fullscreen mode Exit fullscreen mode
Explanation:
- The
Department
entity has aList<Employee>
to represent multiple employees. -
@ManyToOne
inEmployee
establishes a relationship where many employees belong to one department. -
@JoinColumn(name = "department_id")
inEmployee
stores the foreign key reference to theDepartment
table.
Tip: The cascade = CascadeType.ALL
in Department
ensures that deleting a department also removes all associated employees.
2️⃣ Many-to-One Using a Join Table ️
Sometimes, instead of storing a foreign key in the child table, you might want a separate table to manage the relationship.
Modify the Employee
Entity
<span>@ManyToOne</span><span>(</span><span>cascade</span> <span>=</span> <span>CascadeType</span><span>.</span><span>ALL</span><span>)</span><span>@JoinTable</span><span>(</span><span>name</span> <span>=</span> <span>"employee_department"</span><span>,</span><span>joinColumns</span> <span>=</span> <span>@JoinColumn</span><span>(</span><span>name</span> <span>=</span> <span>"employee_id"</span><span>),</span><span>inverseJoinColumns</span> <span>=</span> <span>@JoinColumn</span><span>(</span><span>name</span> <span>=</span> <span>"department_id"</span><span>)</span><span>)</span><span>private</span> <span>Department</span> <span>department</span><span>;</span><span>@ManyToOne</span><span>(</span><span>cascade</span> <span>=</span> <span>CascadeType</span><span>.</span><span>ALL</span><span>)</span> <span>@JoinTable</span><span>(</span> <span>name</span> <span>=</span> <span>"employee_department"</span><span>,</span> <span>joinColumns</span> <span>=</span> <span>@JoinColumn</span><span>(</span><span>name</span> <span>=</span> <span>"employee_id"</span><span>),</span> <span>inverseJoinColumns</span> <span>=</span> <span>@JoinColumn</span><span>(</span><span>name</span> <span>=</span> <span>"department_id"</span><span>)</span> <span>)</span> <span>private</span> <span>Department</span> <span>department</span><span>;</span>@ManyToOne(cascade = CascadeType.ALL) @JoinTable( name = "employee_department", joinColumns = @JoinColumn(name = "employee_id"), inverseJoinColumns = @JoinColumn(name = "department_id") ) private Department department;
Enter fullscreen mode Exit fullscreen mode
This creates an employee_department table that holds employee_id
and department_id
, linking both tables.
When to Use Many-to-One Mapping?
Many-to-One relationships are useful when:
Multiple child entities are linked to a single parent (e.g., employees in a department).
You need to maintain data integrity by enforcing a clear relationship.
You want to avoid duplicate data while ensuring efficient queries.
Conclusion
In this article, we explored:
- What Many-to-One mapping is.
- How to implement it in Spring Boot using JPA.
- Different approaches (foreign key vs. join table).
- When to use it in real-world applications.
Many-to-One mapping is one of the most widely used relationships in databases. Understanding it will help you build scalable applications efficiently!
Have questions? Let me know in the comments! Happy coding!
暂无评论内容