The @OneToMany annotation helps connect one object to many related objects in a simple way. It models real-life situations where one thing owns or controls many others.
@OneToMany relationship in Spring Boot
Start learning this pattern below
Jump into concepts and practice - no test required
@OneToMany(mappedBy = "fieldName", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<RelatedEntity> relatedEntities;mappedBy to tell which field owns the relationship on the other side.cascade to manage related data automatically and fetch to control when data loads.customer field in Order owns the link.@OneToMany(mappedBy = "customer")
private List<Order> orders;@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private Set<Comment> comments = new HashSet<>();
This example shows two classes: Customer and Order. One customer can have many orders. The @OneToMany annotation in Customer links to the list of orders. The Order class uses @ManyToOne to point back to its customer. When you save a customer, all their orders save too because of cascade = CascadeType.ALL.
import jakarta.persistence.*; import java.util.List; import java.util.ArrayList; @Entity public class Customer { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List<Order> orders = new ArrayList<>(); // Constructors, getters, setters public Customer() {} public Customer(String name) { this.name = name; } public Long getId() { return id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Order> getOrders() { return orders; } public void setOrders(List<Order> orders) { this.orders = orders; } } @Entity public class Order { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String product; @ManyToOne @JoinColumn(name = "customer_id") private Customer customer; // Constructors, getters, setters public Order() {} public Order(String product, Customer customer) { this.product = product; this.customer = customer; } public Long getId() { return id; } public String getProduct() { return product; } public void setProduct(String product) { this.product = product; } public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } } // Usage example (in a service or main method): // Customer cust = new Customer("Alice"); // Order order1 = new Order("Book", cust); // Order order2 = new Order("Pen", cust); // cust.setOrders(List.of(order1, order2)); // Save cust to database, orders saved automatically due to cascade.
Always keep mappedBy consistent to avoid errors.
Lazy fetch means related data loads only when needed, saving memory.
Cascade helps keep related data in sync automatically.
@OneToMany connects one object to many others, like one person to many things.
Use mappedBy to tell which side owns the relationship.
Cascade and fetch options control how related data is saved and loaded.
Practice
@OneToMany annotation represent in Spring Boot JPA?Solution
Step 1: Understand the meaning of @OneToMany
The annotation defines a connection where one object relates to multiple objects, like one author having many books.Step 2: Differentiate from other relationships
@ManyToOne is the opposite, linking many entities to one. @OneToMany specifically means one to many.Final Answer:
A relationship where one entity is linked to many entities -> Option AQuick Check:
@OneToMany = one to many link [OK]
- Confusing @OneToMany with @ManyToOne
- Thinking it deletes entities automatically
- Assuming it controls fetch type only
@OneToMany relationship in an entity class?Solution
Step 1: Check the collection type for @OneToMany
@OneToMany requires a collection like List or Set to hold multiple related entities, so List<Child> is correct.Step 2: Verify the mappedBy attribute usage
mappedBy should point to the field name in the Child entity that owns the relationship, here "parent" is correct.Final Answer:
@OneToMany(mappedBy = "parent") private List<Child> children; -> Option AQuick Check:
Use collection + mappedBy for correct syntax [OK]
- Using single object instead of collection
- Wrong mappedBy value
- Using Map instead of List or Set
Department entity?@Entity
public class Department {
@Id
private Long id;
@OneToMany(mappedBy = "department", fetch = FetchType.EAGER)
private List<Employee> employees;
// getters and setters
}Assuming the department has 3 employees, what happens when you load the department?
Solution
Step 1: Understand fetch type EAGER
FetchType.EAGER means related entities are loaded immediately with the main entity.Step 2: Apply to the employees list
Since employees are marked EAGER, all 3 employees will be loaded when the department is fetched.Final Answer:
The department loads with all 3 employees immediately -> Option CQuick Check:
FetchType.EAGER loads related entities immediately [OK]
- Confusing EAGER with LAZY fetch
- Assuming default fetch loads lazily
- Expecting errors from fetch type
@OneToMany mapping:@Entity
public class Order {
@Id
private Long id;
@OneToMany
private List<Item> items;
// getters and setters
}Why might this cause issues when saving an Order with Items?
Solution
Step 1: Check ownership in bidirectional @OneToMany
Without mappedBy, JPA doesn't know which side owns the relationship, causing extra join tables or errors.Step 2: Understand impact on saving
Without ownership, saving Order and Items may not link properly, causing data inconsistency.Final Answer:
Missing mappedBy causes owning side confusion -> Option BQuick Check:
mappedBy defines owner, missing it causes issues [OK]
- Omitting mappedBy in bidirectional relationships
- Confusing collection types for @OneToMany
- Misusing @ManyToMany instead of @OneToMany
Category and all its related Product entities automatically. Which @OneToMany configuration achieves this behavior?Solution
Step 1: Understand cascade and orphanRemoval
CascadeType.ALL applies all operations including delete to related entities. orphanRemoval=true removes child entities if removed from parent.Step 2: Apply to deleting Category
With cascade ALL and orphanRemoval, deleting Category deletes all linked Products automatically.Final Answer:
@OneToMany(mappedBy = "category", cascade = CascadeType.ALL, orphanRemoval = true) private List<Product> products; -> Option DQuick Check:
Use cascade ALL + orphanRemoval for auto-delete [OK]
- Forgetting cascade causes children to remain
- Using only cascade PERSIST won't delete children
- Ignoring orphanRemoval for child removal
