Implementing One-to-One Mapping in Spring Boot – A Hands‑On Walkthrough
- Nishadil
- September 09, 2026
- 0 Comments
- 5 minutes read
- 6 Views
- Save
- Follow Topic
Step‑by‑step guide to link a Student entity with an AadhaarCard using JPA’s @OneToOne annotation
Learn how to model a strict one‑to‑one relationship in Spring Boot with JPA, from project setup to CRUD testing, using a Student‑Aadhaar example.
When you hear "one‑to‑one" in the world of databases, picture a perfect partnership – each record on one side has exactly one counterpart on the other. In a Spring Boot app that usually means sprinkling a couple of JPA annotations and letting Hibernate do the heavy lifting.
In this article we’ll walk through a tiny, yet complete, example: a Student entity that owns a single AadhaarCard. The idea is simple – one student, one Aadhaar – but getting the JPA wiring right can be a bit fiddly if you haven’t done it before.
What you’ll need
- Java 11 (or newer)
- Maven
- MySQL (any recent version)
- An IDE – IntelliJ, Eclipse, VS Code, whatever you like
- Spring Initializr (just click a button and download a starter zip)
1. Bootstrap the Spring Boot project
Head over to start.spring.io and pick the following options:
- Project: Maven
- Language: Java
- Spring Boot: 2.5.6 (or any 2.x you’re comfortable with)
- Packaging: JAR
- Java: 11
- Dependencies: Spring Web, Spring Data JPA, MySQL Driver
Hit Generate, unzip the archive, and open it as a Maven project in your IDE. Maven will pull in the dependencies – give it a minute.
2. Wire up the database
We’ll store everything in a local MySQL schema called mapping. Add these lines to src/main/resources/application.properties (replace the password with yours):
spring.datasource.url=jdbc:mysql://localhost:3306/mapping
spring.datasource.username=root
spring.datasource.password=your_password
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
The ddl-auto=update flag tells Hibernate to create or adjust tables automatically – perfect for a demo.
3. Define the entities
Inside a new package com.example.mapping.models create two POJOs. First, the StudentInformation class:
package com.example.mapping.models;
import javax.persistence.*;
@Entity
@Table(name = "student")
public class StudentInformation {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int rollno;
private String name;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "aadhaar_id") // foreign‑key column in student table
private AadhaarCard aadhaarCard;
// constructors, getters, setters omitted for brevity
}
Notice the @OneToOne annotation – it says “this student owns exactly one AadhaarCard”. The @JoinColumn tells Hibernate to add a column named aadhaar_id in the student table that points to the primary key of aadhaar_card. By using cascade = CascadeType.ALL we make sure that persisting a student automatically persists its card, and likewise for deletions.
Now the partner entity, AadhaarCard:
package com.example.mapping.models;
import javax.persistence.*;
@Entity
@Table(name = "aadhaar_card")
public class AadhaarCard {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String aadhaarNumber;
// constructors, getters, setters omitted for brevity
}
This side doesn’t need a reference back to StudentInformation unless you want a bi‑directional link – for a simple demo a uni‑directional mapping keeps things tidy.
4. Create the repository layer
Spring Data JPA lets us skip the boilerplate DAO code. In com.example.mapping.repository add two interfaces:
package com.example.mapping.repository;
import com.example.mapping.models.StudentInformation;
import org.springframework.data.jpa.repository.JpaRepository;
public interface StudentRepo extends JpaRepository {}
package com.example.mapping.repository;
import com.example.mapping.models.AadhaarCard;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AadhaarRepo extends JpaRepository {}
That’s it – Spring will generate the implementations at runtime.
5. Seed some data with CommandLineRunner
To see everything in action we’ll insert a couple of rows when the app boots. Open the main class (MappingApplication) and make it implement CommandLineRunner:
package com.example.mapping;
import com.example.mapping.models.AadhaarCard;
import com.example.mapping.models.StudentInformation;
import com.example.mapping.repository.StudentRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MappingApplication implements CommandLineRunner {
@Autowired
private StudentRepo studentRepo;
public static void main(String[] args) {
SpringApplication.run(MappingApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
AadhaarCard card = new AadhaarCard("1234-5678-9012");
StudentInformation student = new StudentInformation();
student.setName("Rohit Sharma");
student.setAadhaarCard(card);
studentRepo.save(student); // cascades and persists the card as well
}
}
Start the application (e.g., run mvn spring-boot:run) and watch the console – you’ll see the INSERT statements because we turned show‑sql on earlier.
6. Verify with a quick query
If you connect to MySQL and run SELECT * FROM student; you’ll notice a column aadhaar_id that holds the foreign key. A second query on aadhaar_card will show the matching row. That’s the one‑to‑one relationship in action.
7. A few gotchas
- Make sure the foreign‑key column is unique if you want the database to enforce the one‑to‑one rule on its own. Add
unique = trueto@JoinColumnor create a unique constraint manually. - If you need a bi‑directional link, add a
@OneToOne(mappedBy = "aadhaarCard")field inAadhaarCardand be careful with JSON serialization (use@JsonIgnoreto avoid infinite recursion). - Lazy loading is the default for @OneToOne, but you can force eager fetching with
fetch = FetchType.EAGER– just remember it may affect performance.
That’s pretty much everything you need to get a clean one‑to‑one mapping up and running. From here you can expose REST endpoints, add validation, or even switch to a different database – the JPA mapping stays the same.
Happy coding!
Editorial note: Nishadil may use AI assistance for news drafting and formatting. Readers can report issues from this page, and material corrections are reviewed under our editorial standards.