Introduction

When working with relational databases in Java, JPA (Java Persistence API) makes it easier to map relationships between entities. One of the most fundamental relationships is One-to-One mapping. In this blog, we'll break it down in a way that makes it simple and enjoyable to learn!

By the end of this article, you'll understand:

  • What One-to-One mapping is.
  • How to implement it in Spring Boot with JPA and Hibernate.
  • The different ways to set up the relationship.
  • Practical use cases for real-world applications.

Let's dive in! 🚀


What is One-to-One Mapping?

A One-to-One relationship means that one entity is associated with exactly one other entity. For example:

  • A User can have exactly one Profile.
  • A Car can have exactly one Engine.

In database terms, this means that the primary key of one table is linked to the primary key of another table.

How Does One-to-One Mapping Work in JPA?

JPA provides the @OneToOne annotation to define this relationship. There are different ways to implement it, depending on how you design your database:

  1. Using a Foreign Key (Recommended)
  2. Using a Shared Primary Key 🔑
  3. Using a Join Table 🏛️

Let's see how we can implement these approaches in Spring Boot!


Implementing One-to-One Mapping in Spring Boot

Image description

1️⃣ One-to-One Mapping Using a Foreign Key (Recommended)

The most common way to set up a One-to-One relationship is by using a foreign key. Here’s how we do it:

📌 Step 1: Create the User Entity

import jakarta.persistence.*;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "profile_id", referencedColumnName = "id")
    private Profile profile;

    // Getters and Setters
}

📌 Step 2: Create the Profile Entity

import jakarta.persistence.*;

@Entity
public class Profile {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String bio;
    private String website;

    // Getters and Setters
}

🔹 In the User entity, we used @OneToOne and @JoinColumn(name = "profile_id") to specify that the profile_id column in the User table acts as a foreign key pointing to the id column in the Profile table.


2️⃣ One-to-One Mapping Using a Shared Primary Key

In this approach, the primary key of one table is also used as the primary key of another table.

📌 Update the Profile Entity

@Entity
public class Profile {
    @Id
    private Long id;
    private String bio;
    private String website;

    @OneToOne
    @MapsId
    @JoinColumn(name = "id")
    private User user;
}

🔹 The @MapsId annotation ensures that the Profile entity shares the same primary key as User.


3️⃣ One-to-One Mapping Using a Join Table

Sometimes, you may want a third table to manage the relationship. In this case, JPA allows us to use @JoinTable.

📌 Modify the User Entity

@OneToOne(cascade = CascadeType.ALL)
@JoinTable(name = "user_profile",
           joinColumns = @JoinColumn(name = "user_id"),
           inverseJoinColumns = @JoinColumn(name = "profile_id"))
private Profile profile;

🔹 This approach creates a user_profile table that holds the user_id and profile_id columns, acting as a bridge between User and Profile.


When to Use One-to-One Mapping?

One-to-One relationships are useful in scenarios where:
✅ The related data is rarely accessed separately (e.g., user profile information).
✅ You need data integrity with clear ownership (e.g., a unique identity document per user).
✅ You want to simplify queries and avoid data duplication.


Conclusion 🎯

In this article, we explored:

  • What One-to-One mapping is.
  • Three ways to implement it in Spring Boot with JPA.
  • When to use each approach.

One-to-One mapping is a powerful way to structure your database relationships effectively. Mastering it will help you build better, more scalable applications! 🚀

💬 Got questions or feedback? Drop a comment below! Happy coding! 😃