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 mappingcascade = 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.