JPA Entity Relationships — Owning Side, Inverse Side, Mapping
Fast recall
Quick revision
Core answer
mappedBy). For @ManyToOne/@OneToMany: `@ManyToOne` is always the owning side — the FK lives on its table. `@OneToMany(mappedBy=...)` is the inverse — it reads but doesn't write. Missing `mappedBy` is the classic bug — Hibernate creates an extra join table instead of using the FK. For @ManyToMany: one side owns the join table; changes to the inverse side are silently ignored. Bidirectional relationships need helper methods that update both sides. Collection choice: `Set` for `@ManyToMany` (List causes delete-all-and-reinsert), `List` with `@OrderColumn` when order matters, business-key `equals/hashCode` (never ID-based) to survive the unsaved-then-saved transition.Whether the candidate understands owning vs inverse side and can map relationships correctly
Not setting `mappedBy` on `@OneToMany` — Hibernate creates an extra join table instead of using the FK on the `@ManyToOne` side
Explain why bidirectional `@ManyToMany` should use `Set`, the junction-entity pattern, and the business-key `equals/hashCode` rule
Interview-ready guide
Interview answer
JPA relationships hinge on understanding owning side vs inverse side.
Owning vs inverse:
- The owning side holds the FK column — for
@OneToMany/@ManyToOne, that's@ManyToOne - The inverse side declares
mappedBy— reads the relationship, never writes it - Hibernate persists only changes made to the owning side
The `mappedBy` bug:
@OneToManywithoutmappedBycreates a third join table — usually wrong- Add
mappedBy = "order"to use the FK already on the child table
`@ManyToMany` with `Set`:
Listtriggers DELETE-all + INSERT-survivors on any changeSetonly inserts/deletes the affected row- Use
Setalways; use a junction entity when the relationship has metadata
Bidirectional sync helpers:
addItemandremoveItemmethods that set both sides- Without them, in-memory state diverges from database state in the same transaction
`equals`/`hashCode`:
- Never base on the ID — ID is null before save, set after
- Use a business key or a UUID generated in the constructor
Defaults to override:
@ManyToOneand@OneToOnedefault EAGER — make them LAZY@OneToManydefaults LAZY — keep it that way
JPA Entity Relationships — Owning Side, Inverse Side, Mapping
Direct Answer
JPA relationships have two concepts that explain every mapping bug: the owning side (holds the foreign key column) and the inverse side (declared with mappedBy). For @ManyToOne/@OneToMany: @ManyToOne is always the owning side — the FK lives on its table. @OneToMany(mappedBy=...) is the inverse — it reads but doesn't write. Missing mappedBy is the classic bug — Hibernate creates an extra join table instead of using the FK. For @ManyToMany: one side owns the join table; changes to the inverse side are silently ignored. Bidirectional relationships need helper methods that update both sides. Collection choice: Set for @ManyToMany (List causes delete-all-and-reinsert), List with @OrderColumn when order matters, business-key equals/hashCode (never ID-based) to survive the unsaved-then-saved transition.
Common Mistakes & Pitfalls
Not setting mappedBy on @OneToMany — Hibernate creates an extra join table instead of using the FK on the @ManyToOne side
Check your understanding
Answer these without looking back at the article.
- Why is ID-based `equals/hashCode` problematic for entities in a `Set`?
- How would you migrate a `@ManyToMany` relationship to a junction entity without losing data?
- What goes wrong when you cascade `REMOVE` across a `@ManyToMany`?
- Why does LAZY on `@OneToOne` inverse side require bytecode enhancement?
Related interview prep categories
2Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.