Di bagian contoh @OneToMany
referensi anotasi JPA :
Contoh 1-59 @OneToMany - Kelas Pelanggan dengan Generik
@Entity
public class Customer implements Serializable {
...
@OneToMany(cascade=ALL, mappedBy="customer")
public Set<Order> getOrders() {
return orders;
}
...
}
Contoh 1-60 @ManyToOne - Kelas Pemesanan Dengan Generik
@Entity
public class Order implements Serializable {
...
@ManyToOne
@JoinColumn(name="CUST_ID", nullable=false)
public Customer getCustomer() {
return customer;
}
...
}
Menurut saya Customer
entitas itu adalah pemilik asosiasi. Namun, dalam penjelasan untuk mappedBy
atribut dalam dokumen yang sama, ada tertulis bahwa:
jika hubungan dua arah, maka setel elemen yang dipetakan oleh sisi terbalik (tidak memiliki) asosiasi ke nama bidang atau properti yang memiliki hubungan seperti Contoh 1-60 tunjukkan.
Namun, jika saya tidak salah, sepertinya dalam contoh, mappedBy
sebenarnya ditentukan pada sisi yang memiliki asosiasi, bukan sisi yang tidak memiliki.
Jadi pertanyaan saya pada dasarnya:
Dalam asosiasi bidirectional (satu-ke-banyak / banyak-ke-satu), entitas mana yang merupakan pemilik? Bagaimana kita dapat menetapkan Satu sisi sebagai pemilik? Bagaimana kita dapat menunjuk sisi Banyak sebagai pemilik?
Apa yang dimaksud dengan "sisi terbalik dari asosiasi"? Bagaimana kita dapat menetapkan Satu sisi sebagai kebalikannya? Bagaimana kita dapat menunjuk sisi Banyak sebagai kebalikannya?
Jawaban:
Untuk memahami ini, Anda harus mundur selangkah. Di OO, pelanggan memiliki pesanan (pesanan adalah daftar di objek pelanggan). Tidak mungkin ada pesanan tanpa pelanggan. Jadi pelanggan tampaknya menjadi pemilik pesanan.
Tetapi di dunia SQL, satu item akan benar-benar berisi pointer ke item lainnya. Karena ada 1 pelanggan untuk pesanan N, setiap pesanan berisi kunci asing ke pelanggan miliknya. Ini adalah "koneksi" dan ini berarti urutan "memiliki" (atau secara harfiah berisi) koneksi (informasi). Ini persis kebalikan dari dunia OO / model.
Ini dapat membantu untuk memahami:
Sisi terbalik adalah OO "pemilik" objek, dalam hal ini pelanggan. Pelanggan tidak memiliki kolom di tabel untuk menyimpan pesanan, jadi Anda harus memberi tahu di mana di tabel pesanan dapat menyimpan data ini (yang terjadi melalui
mappedBy
).Contoh umum lainnya adalah pohon dengan simpul yang dapat berupa orang tua dan anak-anak. Dalam hal ini, kedua bidang digunakan dalam satu kelas:
Ini menjelaskan untuk karya desain banyak "kunci asing". Ada pendekatan kedua yang menggunakan tabel lain untuk mempertahankan hubungan. Itu berarti, untuk contoh pertama kami, Anda memiliki tiga tabel: Satu dengan pelanggan, satu dengan pesanan dan tabel dua kolom dengan pasangan kunci utama (customerPK, orderPK).
Pendekatan ini lebih fleksibel daripada yang di atas (dapat dengan mudah menangani satu-ke-satu, banyak-ke-satu, satu-ke-banyak dan bahkan banyak-ke-banyak). Harganya adalah itu
Itu sebabnya saya jarang merekomendasikan pendekatan ini.
sumber
@Parent
atau@Child
anotasi daripada "XtoY" untuk menyatakan apa artinya koneksi (daripada bagaimana penerapannya )Luar biasa, dalam 3 tahun tidak ada yang menjawab pertanyaan luar biasa Anda dengan contoh kedua cara untuk memetakan hubungan.
Seperti yang disebutkan oleh orang lain, sisi "pemilik" berisi pointer (kunci asing) dalam database. Anda dapat menetapkan kedua sisi sebagai pemilik, namun, jika Anda menunjuk satu sisi sebagai pemilik, hubungan tidak akan bersifat dua arah (sisi terbalik "banyak" yang tidak akan memiliki pengetahuan tentang "pemilik" -nya). Ini dapat diinginkan untuk enkapsulasi / kopling longgar:
Satu-satunya solusi pemetaan dua arah adalah memiliki sisi "banyak" yang memiliki penunjuk ke "satu", dan menggunakan atribut @OneToMany "mappedBy". Tanpa atribut "mappedBy" Hibernate akan mengharapkan pemetaan ganda (database akan memiliki kolom bergabung dan tabel bergabung, yang berlebihan (biasanya tidak diinginkan)).
sumber
Entitas yang memiliki tabel dengan kunci asing dalam database adalah entitas yang memiliki dan tabel lainnya, yang ditunjuk, adalah entitas terbalik.
sumber
Aturan sederhana hubungan dua arah:
1.Untuk banyak hubungan dua arah, banyak pihak selalu merupakan pihak yang memiliki hubungan tersebut. Contoh: 1 Kamar memiliki banyak Orang (satu Orang hanya memiliki satu Kamar) -> pihak yang memiliki adalah Orang
2.Untuk hubungan dua arah satu-ke-satu, pihak yang memiliki sesuai dengan sisi yang berisi kunci asing yang sesuai.
3. Untuk hubungan dua arah banyak-ke-banyak, masing-masing pihak mungkin merupakan pihak yang memiliki.
Semoga bisa membantu Anda.
sumber
Untuk dua Pelanggan dan Pesanan Kelas Entitas, hibernasi akan membuat dua tabel.
Kemungkinan Kasus:
mappedBy tidak digunakan di kelas Customer.java dan Order.java->
Di sisi pelanggan, tabel baru akan dibuat [nama = CUSTOMER_ORDER] yang akan menyimpan pemetaan CUSTOMER_ID dan ORDER_ID. Ini adalah kunci utama Tabel Pelanggan dan Pesanan. Di sisi Pesanan, kolom tambahan diperlukan untuk menyimpan pemetaan catatan Customer_ID yang sesuai.
mappedBy digunakan di Customer.java [Seperti yang diberikan dalam pernyataan masalah] Sekarang tabel tambahan [CUSTOMER_ORDER] tidak dibuat. Hanya satu kolom di Tabel Pesanan
mappedby digunakan di Order.java Sekarang tabel tambahan akan dibuat oleh hibernate. [name = CUSTOMER_ORDER] Tabel Pesanan tidak akan memiliki kolom [Customer_ID] tambahan untuk pemetaan.
Sisi mana pun bisa dijadikan Pemilik hubungan. Tapi lebih baik memilih sisi xxxToOne.
Efek pengkodean -> Hanya sisi yang dimiliki entitas yang dapat mengubah status hubungan. Dalam contoh di bawah ini, kelas BoyFriend adalah pemilik hubungan. bahkan jika Pacar ingin putus, dia tidak bisa.
sumber
Hubungan tabel vs hubungan entitas
Dalam sistem basis data relasional, hanya ada tiga jenis hubungan tabel:
Jadi,
one-to-many
hubungan tabel terlihat sebagai berikut:Perhatikan bahwa hubungan didasarkan pada kolom Kunci Asing (misalnya,
post_id
) di tabel anak.Jadi, ada satu sumber kebenaran ketika datang untuk mengelola
one-to-many
hubungan tabel.Sekarang, jika Anda mengambil hubungan entitas dua arah yang memetakan pada
one-to-many
hubungan tabel yang kita lihat sebelumnya:Jika Anda melihat diagram di atas, Anda dapat melihat bahwa ada dua cara untuk mengelola hubungan ini.
Di
Post
entitas, Anda memilikicomments
koleksi:Dan, dalam
PostComment
,post
asosiasi dipetakan sebagai berikut:Jadi, Anda memiliki dua sisi yang dapat mengubah asosiasi entitas:
comments
koleksi anak,post_comment
baris baru harus dikaitkan denganpost
entitas induk melaluipost_id
kolomnya.post
propertiPostComment
entitas,post_id
kolom juga harus diperbarui.Karena ada dua cara untuk mewakili kolom Kunci Asing, Anda harus menentukan mana sumber kebenaran ketika harus menerjemahkan perubahan status asosiasi menjadi modifikasi nilai kolom Kunci Asing yang setara.
MappedBy (alias sisi terbalik)
The
mappedBy
atribut mengatakan bahwa@ManyToOne
sisi bertugas mengelola kolom Foreign Key, dan koleksi hanya digunakan untuk mengambil entitas anak dan untuk kaskade perubahan induk entitas negara untuk anak-anak (misalnya, menghapus orang tua juga harus menghapus entitas anak).Sinkronkan kedua sisi dari asosiasi dua arah
Sekarang, bahkan jika Anda mendefinisikan
mappedBy
atribut dan@ManyToOne
asosiasi sisi anak mengelola kolom Kunci Asing, Anda masih perlu menyinkronkan kedua sisi dari asosiasi dua arah.Cara terbaik untuk melakukannya adalah dengan menambahkan dua metode utilitas ini:
Metode
addComment
danremoveComment
memastikan kedua belah pihak disinkronkan. Jadi, jika kita menambahkan entitas anak, entitas anak perlu menunjuk ke induk dan entitas induk harus memiliki anak yang terkandung dalam koleksi anak.sumber