Spring Boot: JPA Many-to-One Mapping

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 a List<Employee> to represent multiple employees.
  • @ManyToOne in Employee establishes a relationship where many employees belong to one department.
  • @JoinColumn(name = "department_id") in Employee stores the foreign key reference to the Department 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!

原文链接:Spring Boot: JPA Many-to-One Mapping

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享
Suffer all the pain can destroy a person, but it also can kill the pain.
一切痛苦能够毁灭人,然而受苦的人也能把痛苦消灭
评论 抢沙发

请登录后发表评论

    暂无评论内容