top of page
Search

JPA Relationships Made Simple: mappedBy vs JoinColumn Explained

  • Writer: Gigs Logic
    Gigs Logic
  • Sep 17, 2025
  • 4 min read

JPA mapping shuru mein thoda confusing lagta hai — mappedBy kahan, JoinColumn kahan?But once you understand who owns the foreign key, everything becomes easy.

Let’s understand step by step.


🔹 Rules to remember:

Core rule: The side with the foreign key is the owner.

In relational DBs, foreign keys always live on the “many” side

So in practice:

  • @ManyToOne is almost always the owner (with @JoinColumn).

  • @OneToMany is usually the inverse side (with mappedBy).



    1. One to Many/ Many to One


Let’s consider that one customer can have multiple orders, and various orders can be associated with one customer.

That would mean:


  • Ek Customer ke multiple Orders ho sakte hain.


Example: Customer Rahul placed 3 orders → Order #101, Order #102, Order #103. So multiple orders belong to the same customer.

  • Ek Order sirf ek Customer ka hoga.(Here, the order means the order record identified by Order ID, which could be useful for generating an invoice for a particular customer)


Example: Order #101 can’t belong to both Ashish and Rahul. It must have exactly one customer (otherwise payment/shipping hi gadbad ho jaayegi 😅


🔹 Database Design



  • order table will have a customer_id foreign key column.


So, in this case, the Order class is the owner, so it would have @JoinColumn and the Customer class would have mappedBy.


Now, the question is, how is Order class the owner?


🔹 Rule of Thumb


The owner is the side that has the foreign key column in the database table. In relational DBs, foreign keys always live on the “many” side.

➤ In this mapping, the Order table carries the customer_id foreign key.➤The Customer.orders field is just a mirror — it doesn’t create any extra column.➤The owning side is Order.customer because it actually defines the foreign key column (customer_id).➤The inverse side isCustomer.orders, where mappedBy simply tells Hibernate:


“Don’t generate a new column. Just use the one that already exists in Order.customer.”


Pro tip: Agar tum mappedBy chhod doge aur sirf @OneToMany likhoge Customer side par, Hibernate bolega:



“Bhai, foreign key kahan hai? Chal, main apna ek naya join table bana leta hoon.” 😅


Result? You’ll end up with an extra table like:



But that’s totally redundant, kyunki Order table me already customer_id foreign key hai.


👉 Moral of the story:


  • mappedBy = tell Hibernate “chill, the column already exists on the other side.”

  • Without mappedBy Hibernate will eagerly create its own join table and add unnecessary complexity.


Example of One-to-Many/Many-to-One Relationship



Socho Flipkart se order kar rahe ho. Tumhare (Customer) account se 5 alag orders nikle — kaam simple hai, ek hi foreign key (customer_id) se sab Orders tumse link ho jaate. Lekin ek order agar 2 customers ke hote, toh DB bolta — “bhai, ye kya jugad hai?”



2. One-to-One Mapping

Let’s take an example Person <-> Passport


  • Ek Person ke paas sirf ek Passport hota hai.

  • Ek Passport sirf ek Person ka hota hai.


👉 Pure one-to-one relationship.



👉 The passport table contains the person_id foreign key.

👉 One passport → one person.

👉 One person → one passport.


🔹 Why is Passport table the owner here?


  • Because @JoinColumn lives in Passport → means the Passport table will have person_id as a foreign key.

  • Person table won’t have anything special.

  • A Passport depends on a Person.

  • Without a Person, a Passport makes no sense.

  • So Passport table keeps person_id as FK → Passport is the owner. ✅


Socho tumhare paas ek hi passport hai. Agar tumhe 2 passport mil jaaye toh government bolegi “bhai, illegal kaam mat kar” 😂. Isi liye DB design bhi strict hai — ek person ke liye ek hi passport allowed.


3. Many to Many mapping


A Many-to-Many relationship can’t be directly represented in a relational database.


🔹 Why?

  • One Student can enroll in many Courses.

  • One Course can have many Students.


Now, if we try to store this directly:

  • You can’t keep multiple course_ids in a single Student row.

  • You also can’t keep multiple student_ids in a single Course row.

👉 That would break normalization rules.

Solution: Use a join table that connects Students and Courses.


🔹 Why Do We Need a Join Table?


Let’s take Student ↔ Course:

  • A student can be enrolled in multiple courses.

  • A course can have multiple students.


But where do we put these multiple IDs?

  • If we try course_id1, course_id2... in Student → messy and violates normalization..

  • If we try student_id1, student_id2... in the Course → same problem.


So the clean solution is:👉 Create a join table that stores pairs of (student_id, course_id).

This join table acts as a bridge and maintains a proper normalized structure.


Entities Example: Student ↔ Course






🔹 How @JoinTable Works




1. name = "student_course"

  • This is the name of the join table in the database.

  • It will contain only the foreign keys pointing to both tables.


2. joinColumns = @JoinColumn(name = "student_id")

  • This column in the join table refers to the current entity (here, Student).

  • Acts as a foreign key to Student.id.

  • So student_id is a foreign key in the join table → references Student.id in the Student table


3. inverseJoinColumns = @JoinColumn(name = "course_id")

  • This column in the join table refers to the other entity (here, Course).

  • Acts as a foreign key to Course.id.


🔹 Bidirectional Mapping



mappedBy = "courses" tells Hibernate:


  • “This is the inverse side; don’t create another join table. Just use the one defined in Student.”


Hibernate will automatically synchronise both sides.

Without mappedBy Hibernate would try to create another join table, which is redundant.


This was a high-level breakdown of how One-to-Many / Many-to-One, /One-to -One and Many-to-Many mappings actually work in JPA. Want me to dive deeper into things like cascading, lazy loading? Drop a comment below!


🚀 Follow for more such backend breakdowns!

 
 
 

Comments


Wireless Computer Accessories
  • Instagram
© 2025 by Gigs Logic . All rights reserved.
Want to connect?
Get a callback and get things sorted
bottom of page