14 · Hibernate and Spring Data JPA in depth / LESSON 66 OF 102
Many-to-one, one-to-many, and relationship ownership
The owning side of a relationship controls the database link; both Java sides still need consistent state.
Before this lesson: Identifiers, enums, embeddables, and converters
Understand the topic
A many-to-one foreign key usually lives on the child row. In a bidirectional one-to-many association, mappedBy names the child property that owns the relation, not a database column. Use helper methods to update both sides of the in-memory relationship.
Default eager loading for to-one mappings can create unexpected work. Choose fetch behavior deliberately and design queries for each use case. Cascade controls propagated entity operations; it is distinct from database ON DELETE behavior.
EXAMPLE · JAVA
Task relationship fields
// In a Task entity; Owner must be another mapped entity.
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "owner_id", nullable = false)
private Owner owner;
// In Owner: mappedBy names Task.owner.
@OneToMany(mappedBy = "owner")
private java.util.List<Task> tasks = new java.util.ArrayList<>();What to expect
This is a two-file mapping fragment using jakarta.persistence imports. The Task.owner side writes owner_id.
YOUR TURN
Put it into practice
- 01Implement Owner and Task with a bidirectional relationship.
- 02Add an owner helper that updates both the collection and child reference.
- 03Verify: Persist and reload the relationship successfully with a non-null foreign key and consistent Java state.
Pass a quiz or complete a lab to check today’s streak. Each lesson counts once per day, including when you review it later.
UNDER THE HOOD
Build the mental model
The owning side of a relationship controls the database link; both Java sides still need consistent state.
- 01A many-to-one foreign key usually lives on the child row. In a bidirectional one-to-many association, mappedBy names the child property that owns the relation, not a database column. Use helper methods to update both sides of the in-memory relationship.
- 02Default eager loading for to-one mappings can create unexpected work. Choose fetch behavior deliberately and design queries for each use case. Cascade controls propagated entity operations; it is distinct from database ON DELETE behavior.
- 03Trace the example: This is a two-file mapping fragment using jakarta.persistence imports. The Task.owner side writes owner_id.
A mistake worth avoiding
Adding to the parent collection does not update the foreign key.
DEBUGGING ROOM
Something broke. Where do you look?
Adding to the parent collection does not update the foreign key.
Before revealing the diagnosis, write down your first investigation step.
CHECK YOUR UNDERSTANDING
What does mappedBy refer to?
BUILD IT YOURSELF
Implement Owner and Task with a bidirectional relationship.
- 1.Implement Owner and Task with a bidirectional relationship.
- 2.Add an owner helper that updates both the collection and child reference.
- 3.Reproduce this failure, then repair it: Adding to the parent collection does not update the foreign key.
Acceptance checklist
Lab completion is your self-report. Knowledge checks do not certify project quality.
RETRIEVE IT FROM MEMORY
What does mappedBy refer to?
Revisit this lesson in three days after a successful check or lab.
Ready for the next step?
Persist and reload the relationship successfully with a non-null foreign key and consistent Java state.
Reading is separate from passing a knowledge check or completing a lab.