One-to-Many Mapping
1️⃣ Konsep Dasar
Relasi One-to-Many berarti satu baris di tabel utama berhubungan dengan banyak baris di tabel lain.
- Contoh: Satu Kelas (
Classes) memiliki banyak Siswa (Student). - Foreign Key (FK) 🔑: Secara fisik di database, kolom FK (
class_id) selalu diletakkan di sisi "Banyak/Many" yaitu tabel student.
2️⃣ Implementasi Entity (Bi-Directional)
Dalam relasi dua arah, kedua class saling mengenal. Kita menggunakan atribut mappedBy di sisi "One" agar Hibernate tahu bahwa relasi diatur oleh field di sisi "Many".

A. Entity Student (Sisi "Many" / Owner)
Sisi ini yang memegang @JoinColumn.
@Entity
@Table(name = "student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
@JoinColumn(name = "class_id")
private Classes classes;
// Setter & Getter
}
B. Entity Classes (Sisi "One" / Inverse)
Sisi ini menggunakan mappedBy dan memiliki koleksi (List atau Set).
@Entity
@Table(name = "classes")
public class Classes {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "class_name")
private String className;
@OneToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
@JoinColumn(name = "teacher_id")
private Teacher teacher;
@OneToMany(mappedBy = "classes", cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
List<Student> students = new ArrayList<>();
// HELPER METHOD: Sangat penting untuk sinkronisasi 2 arah di memori
// menambah method 'add()' memastikan kedua sisi terhubung secara konsisten dalam memori Java dengan Bi-Direction
public void add(Student student) {
if (students == null) {
students = new ArrayList<>();
}
students.add(student);
if (student != null) {
student.setClasses(this);
}
}
// Setter & Getter
}
C. Kenapa Classes yang menggunakan mappedBy?
Dalam aturan database relasional, Foreign Key (kolom kunci) selalu diletakkan di tabel yang "Banyak/Many" (Student). Karena tabel Student yang memegang kunci fisik di database, maka dalam kode Java:
Studentdisebut sebagai Owner (Pemilik Relasi).Classesdisebut sebagai Inverse Side (Sisi Referensi), sehingga ia harus menggunakanmappedBy.
Ringkasan Aturan mappedBy
| Posisi | Entitas | Anotasi Menggunakan mappedBy? | Keterangan |
|---|---|---|---|
| One | Classes | @OneToMany | Ya |
| Many | Student | @ManyToOne | Tidak |
tip
- Inisialisasi List : Selalu inisialisasi
List<Student> students = new ArrayList<>();di sisiClassesuntuk menghindariNullPointerException. - Helper Method : Disarankan membuat method
addStudent(Student s)di dalam entityClassesuntuk memastikan kedua sisi terhubung secara konsisten dalam memori Java sebelum disimpan ke database menggunakan Spring Data JPA.
Jika dijalankan akan menghasilkan 2 tabel yang saling terhubung:
Hibernate: alter table student add column class_id integer
Hibernate: alter table student add constraint FKnsl7w2nw6o6eq53hqlxfcijpm foreign key (class_id) references classes (id)

3️⃣ Poin Penting
- Lazy vs Eager Fetching: Secara default,
@OneToManybersifat Lazy. Artinya, data siswa tidak akan ditarik dari DB kecuali Anda memanggilgetStudents(). Jika Anda mencoba mengakses data ini setelahsession.close(), akan terjadiLazyInitializationException. mappedBy: Atribut ini sangat krusial. Ini akan memberitahu Hibernate bahwa sisiClasseshanyalah "mirror". Pemilik sebenarnya dari relasi ini adalah sisiStudent(yang memegang FK).- Orphan Removal: Jika Anda menambahkan
orphanRemoval = truepada@OneToMany, maka saat Anda menghapus seorang siswa dariList<Student>, Hibernate akan otomatis menghapus siswa tersebut dari database (bukan hanya mengosongkan FK-nya). - Inisialisasi List: Selalu inisialisasi
Listdengannew ArrayList<>()untuk menghindariNullPointerException.