JPA Entity Relationship Types Overview
Fast recall
Quick revision
Core answer
Whether you can name all four relationship annotations and explain which side owns the foreign key in a bidirectional pair
Not knowing which side owns the relationship, or forgetting that bidirectional relationships need mappedBy on the inverse side
Explain owning side vs inverse side and state that @ManyToOne is always the owning side in a OneToMany/ManyToOne pair because it holds the FK column
Interview-ready guide
Interview answer
The annotations describe cardinality in the object model. An Employee-to-Department field is @ManyToOne; the optional Department-to-employees collection is @OneToMany(mappedBy = "department"). A User-to-Profile association can be @OneToOne, and Student-to-Course can be @ManyToMany through a join table. Bidirectional is not required. Add the reverse field only when the application needs navigation in both directions, then keep both Java references in sync and identify one owner.
JPA Entity Relationship Types Overview
Direct Answer
JPA models four relationship shapes: @OneToOne, @OneToMany, @ManyToOne, and @ManyToMany. A relationship can be unidirectional or bidirectional. A bidirectional relationship has one owning side and one inverse side; mappedBy can appear on @OneToOne, @OneToMany, or @ManyToMany, while @ManyToOne is always an owning side.
Code Example
// Java 17 + Spring Boot 3.2 — jakarta.persistence
import jakarta.persistence.*;
import java.util.*;
// OneToOne: User has one Profile
@Entity
class User {
@Id @GeneratedValue private Long id;
private String username;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "profile_id") // owning side: holds the FK
private Profile profile;
}
// OneToMany / ManyToOne: Department has many Employees
@Entity
class Department {
@Id @GeneratedValue private Long id;
private String name;
@OneToMany(mappedBy = "department") // inverse side
private List<Employee> employees = new ArrayList<>();
}
@Entity
class Employee {
@Id @GeneratedValue private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "department_id") // owning side: holds the FK
private Department department;
}
// ManyToMany: Student enrolls in many Courses
@Entity
class Student {
@Id @GeneratedValue private Long id;
private String name;
@ManyToMany
@JoinTable(name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id"))
private Set<Course> courses = new HashSet<>();
}
@Entity
class Course {
@Id @GeneratedValue private Long id;
private String title;
@ManyToMany(mappedBy = "courses") // inverse side
private Set<Student> students = new HashSet<>();
}
The @JoinColumn/@JoinTable side always owns the relationship; the mappedBy side is read-only navigation.
Common Mistakes & Pitfalls
- Forgetting mappedBy — @OneToMany on Department plus @ManyToOne on Employee without mappedBy creates two separate foreign keys for one relationship. Hibernate can't tell which side to trust.
- Unidirectional @OneToMany alone — a @OneToMany without a matching @ManyToOne forces Hibernate to create a join table instead of a simple FK column. Prefer bidirectional @OneToMany/@ManyToOne.
- Wrong cascade direction — CascadeType.ALL on a @ManyToOne means deleting an Employee tries to delete the whole Department, causing a constraint violation.
Check your understanding
Answer these without looking back at the article.
- What is the mappedBy attribute?
- What is the owning side in a JPA relationship?
- What is a join table in JPA @ManyToMany?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.