Skip to content

🔗 Master OneToMany & ManyToOne: The Relationship Secrets Hibernate Doesn’t Want You to Know 😱

Hibernate relationships are where beginners run scared and veterans get smug.

But guess what? You don’t need a PhD in ORM to master them.
Today, I’m going to break down One-to-Many and Many-to-One relationships so clearly that even your dog could implement them. 🐶

And yes, we’re doing it all with just two classes and a few annotations.

Let’s go!


🧠 The Big Idea

In relational databases:

  • A User can have many Posts
  • But each Post belongs to one User

That’s a One-to-Many and Many-to-One relationship.


🧱 Step 1: Update Your Project Structure

src/
└── main/
└── java/
└── com/example/
├── User.java
├── Post.java ← (new)
├── HibernateUtil.java
└── Main.java

👤 Step 2: Modify User.java

Let’s give users a list of posts.

package com.example;

import jakarta.persistence.*;
import java.util.List;

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "username")
    private String name;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List<Post> posts;

    public User() {}

    public User(String name) {
        this.name = name;
    }

    // Getters and setters for id, name, posts
}

⚠️ mappedBy = "user" means the Post entity owns the relationship. Hibernate won’t create an extra join table.

📝 Step 3: Create Post.java

package com.example;

import jakarta.persistence.*;

@Entity
@Table(name = "posts")
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String title;

    @ManyToOne
    @JoinColumn(name = "user_id") // foreign key in 'posts' table
    private User user;

    public Post() {}

    public Post(String title, User user) {
        this.title = title;
        this.user = user;
    }

    // Getters and setters...
}

⚙️ Step 4: Update hibernate.cfg.xml

Add both classes:

<mapping class="com.example.User"/>
<mapping class="com.example.Post"/>

🚀 Step 5: Test It All

Update Main.java:

package com.example;

import org.hibernate.Session;
import org.hibernate.Transaction;

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();

        User user = new User("Devesh");

        Post post1 = new Post("Hibernate Rocks!", user);
        Post post2 = new Post("ORM Simplified", user);

        user.setPosts(Arrays.asList(post1, post2));

        session.save(user); // cascade will save posts too
        tx.commit();
        session.close();

        System.out.println("User and posts saved!");
    }
}

🧪 Output

Hibernate logs will show it saving the user and two posts, all in one go 🔥


📌 What You Learned

  • @OneToMany and @ManyToOne simplify foreign key mapping
  • cascade = CascadeType.ALL lets you save the parent and children in one shot
  • Hibernate handles everything behind the scenes — SQL who?

🪄 BONUS: Lazy Loading vs Eager Loading

Hibernate uses lazy loading by default for collections like List<Post>.
Want to load posts with users instantly? Add this:

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.EAGER)

Be careful: eager loading can slow down performance if overused.

Leave a Reply

Your email address will not be published. Required fields are marked *