Karena ini adalah pertanyaan yang sangat umum, saya menulis
artikel ini , yang menjadi dasar jawaban ini.
Asosiasi satu-ke-banyak searah
Seperti yang saya jelaskan di artikel ini , jika Anda menggunakan @OneToMany
anotasi dengan @JoinColumn
, maka Anda memiliki asosiasi searah, seperti yang terjadi antara Post
entitas induk dan anak PostComment
dalam diagram berikut:
Saat menggunakan asosiasi satu-ke-banyak searah, hanya sisi induk yang memetakan asosiasi.
Dalam contoh ini, hanya Post
entitas yang akan menentukan @OneToMany
asosiasi ke PostComment
entitas anak :
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "post_id")
private List<PostComment> comments = new ArrayList<>();
Asosiasi dua arah dua arah
Jika Anda menggunakan @OneToMany
dengan mappedBy
atribut set, Anda memiliki hubungan dua arah. Dalam kasus kami, kedua Post
entitas memiliki koleksi PostComment
entitas anak, dan PostComment
entitas anak memiliki referensi kembali ke Post
entitas induk , seperti yang diilustrasikan oleh diagram berikut:
Dalam PostComment
entitas, post
properti entitas dipetakan sebagai berikut:
@ManyToOne(fetch = FetchType.LAZY)
private Post post;
Alasan kami menetapkan fetch
atribut secara eksplisit FetchType.LAZY
adalah karena, secara default, semua @ManyToOne
dan @OneToOne
asosiasi diambil dengan penuh semangat, yang dapat menyebabkan masalah kueri N +1. Untuk detail lebih lanjut tentang topik ini, lihat artikel ini .
Dalam Post
entitas, comments
asosiasi dipetakan sebagai berikut:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
The mappedBy
atribut dari @OneToMany
referensi anotasi post
properti di anak PostComment
entitas, dan, dengan cara ini, Hibernate tahu bahwa hubungan dua arah dikendalikan oleh @ManyToOne
sisi, yang bertugas mengelola nilai kolom Foreign Key hubungan tabel ini didasarkan pada.
Untuk asosiasi dua arah, Anda juga perlu memiliki dua metode utilitas, seperti addChild
dan removeChild
:
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
Kedua metode ini memastikan bahwa kedua sisi dari asosiasi dua arah tidak sinkron. Tanpa menyinkronkan kedua ujungnya, Hibernate tidak menjamin bahwa perubahan status asosiasi akan menyebar ke database.
Untuk detail lebih lanjut tentang cara terbaik untuk menyinkronkan asosiasi dua arah dengan JPA dan Hibernate, lihat artikel ini .
Yang mana yang harus dipilih?
The searah @OneToMany
asosiasi tidak melakukan dengan baik , sehingga Anda harus menghindarinya.
Anda lebih baik menggunakan bidirectional @OneToMany
yang lebih efisien .