Apa perbedaan antara:
@Entity
public class Company {
@OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY)
@JoinColumn(name = "companyIdRef", referencedColumnName = "companyId")
private List<Branch> branches;
...
}
dan
@Entity
public class Company {
@OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY, mappedBy = "companyIdRef")
private List<Branch> branches;
...
}
Jawaban:
Anotasi
@JoinColumn
menunjukkan bahwa entitas ini adalah pemilik hubungan (yaitu: tabel yang sesuai memiliki kolom dengan kunci asing ke tabel yang direferensikan), sedangkan atributmappedBy
menunjukkan bahwa entitas di sisi ini adalah kebalikan dari hubungan, dan pemiliknya berada di entitas "lain". Ini juga berarti bahwa Anda dapat mengakses tabel lain dari kelas yang telah Anda anotasi dengan "mappedBy" (hubungan dua arah penuh).Khususnya, untuk kode dalam pertanyaan, anotasi yang benar akan terlihat seperti ini:
sumber
@JoinColumn
diCompany
Branch
tidak memiliki properti yang mereferensikanCompany
, tetapi tabel di bawahnya memiliki kolom yang memiliki, maka Anda dapat menggunakannya@JoinTable
untuk memetakannya. Ini adalah situasi yang tidak biasa, karena Anda biasanya akan memetakan kolom di objek yang sesuai dengan tabelnya, tetapi itu bisa terjadi, dan itu sah-sah saja.@OneToOne
, baris anak diperbarui dengannull
di kolom FKey mereka yang mereferensikan orang tua.@JoinColumn
bisa digunakan di kedua sisi hubungan. Pertanyaannya adalah tentang penggunaan@JoinColumn
di@OneToMany
samping (kasus yang jarang terjadi). Dan intinya di sini adalah duplikasi informasi fisik (nama kolom) bersama dengan query SQL yang tidak dioptimalkan yang akan menghasilkan beberapaUPDATE
pernyataan tambahan .Menurut dokumentasi :
Karena banyak ke satu (hampir) selalu menjadi sisi pemilik hubungan dua arah dalam spesifikasi JPA, asosiasi satu ke banyak dijelaskan oleh
@OneToMany(mappedBy=...)
Troop
memiliki hubungan dua arah dengan banyak hubunganSoldier
melalui properti pasukan. Anda tidak harus (tidak boleh) mendefinisikan pemetaan fisik apa pun dimappedBy
samping.Untuk memetakan satu arah dua arah ke banyak, dengan sisi satu ke banyak sebagai sisi pemilik , Anda harus menghapus
mappedBy
elemen dan mengatur banyak ke satu@JoinColumn
sebagaiinsertable
danupdatable
ke false. Solusi ini tidak dioptimalkan dan akan menghasilkan beberapaUPDATE
pernyataan tambahan .sumber
mappedBy="troop"
merujuk pada bidang yang mana?mappedBy="troop"
mengacu pada pasukan properti di kelas Soldier. Dalam kode di atas properti tidak terlihat karena di sini Mykhaylo dihilangkan, tetapi Anda dapat menyimpulkan keberadaannya dengan getter getTroop (). Periksa jawaban Óscar López , sangat jelas dan Anda akan mendapatkan intinya.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 antaraPost
entitas induk dan anakPostComment
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 kePostComment
entitas anak :Asosiasi dua arah dua arah
Jika Anda menggunakan
@OneToMany
denganmappedBy
atribut set, Anda memiliki hubungan dua arah. Dalam kasus kami, keduaPost
entitas memiliki koleksiPostComment
entitas anak, danPostComment
entitas anak memiliki referensi kembali kePost
entitas induk , seperti yang diilustrasikan oleh diagram berikut:Dalam
PostComment
entitas,post
properti entitas dipetakan sebagai berikut:Dalam
Post
entitas,comments
asosiasi dipetakan sebagai berikut:The
mappedBy
atribut dari@OneToMany
referensi anotasipost
properti di anakPostComment
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
danremoveChild
: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.
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 .sumber
Anotasi yang dipetakan oleh idealnya harus selalu digunakan di sisi Induk (kelas Perusahaan) dari hubungan dua arah, dalam hal ini harus dalam kelas Perusahaan yang menunjuk ke variabel anggota 'perusahaan' dari kelas Anak (kelas Cabang)
Anotasi @JoinColumn digunakan untuk menentukan kolom yang dipetakan untuk bergabung dengan entitas asosiasi, anotasi ini dapat digunakan di setiap kelas (Orangtua atau Anak) tetapi idealnya harus digunakan hanya di satu sisi (baik di kelas induk atau di kelas Anak tidak di keduanya) di sini dalam kasus ini saya menggunakannya di sisi Anak (kelas Cabang) dari hubungan dua arah yang menunjukkan kunci asing di kelas Cabang.
di bawah ini adalah contoh kerja:
kelas induk, Perusahaan
kelas anak, Cabang
sumber
Saya hanya ingin menambahkan yang
@JoinColumn
tidak selalu harus terkait dengan lokasi informasi fisik seperti jawaban ini menyarankan. Anda bisa menggabungkan@JoinColumn
dengan@OneToMany
bahkan jika tabel induk tidak memiliki data tabel yang menunjuk ke tabel anak.Cara mendefinisikan hubungan OneToMany searah di JPA
OneToMany searah, No Inverse ManyToOne, No Join Table
Tampaknya hanya tersedia di
JPA 2.x+
olah. Ini berguna untuk situasi di mana Anda ingin kelas anak hanya berisi ID dari orang tua, bukan referensi lengkap.sumber
Saya tidak setuju dengan jawaban yang diterima di sini oleh Óscar López. Jawaban itu tidak akurat!
BUKAN
@JoinColumn
yang menunjukkan bahwa entitas ini adalah pemilik hubungan. Sebaliknya, itu adalah@ManyToOne
anotasi yang melakukan ini (dalam contohnya).Anotasi hubungan seperti
@ManyToOne
,@OneToMany
dan@ManyToMany
beri tahu JPA / Hibernate untuk membuat pemetaan. Secara default, ini dilakukan melalui Tabel Gabung yang terpisah.@JoinColumn
Dipetakan oleh
Ingat:
MappedBy
adalah properti anotasi hubungan yang tujuannya adalah untuk menghasilkan mekanisme untuk menghubungkan dua entitas yang secara default mereka lakukan dengan membuat tabel bergabung.MappedBy
menghentikan proses itu dalam satu arah.Entitas yang tidak menggunakan
MappedBy
dikatakan sebagai pemilik hubungan karena mekanisme pemetaan didikte dalam kelasnya melalui penggunaan salah satu dari tiga penjelasan pemetaan terhadap bidang kunci asing. Ini tidak hanya menentukan sifat pemetaan tetapi juga menginstruksikan pembuatan tabel gabungan. Selain itu, opsi untuk menekan tabel bergabung juga ada dengan menerapkan penjelasan @JoinColumn di atas kunci asing yang menyimpannya di dalam tabel entitas pemilik.Jadi dalam ringkasan:
@JoinColumn
baik membuat kolom bergabung baru atau mengganti nama yang sudah ada; sementaraMappedBy
parameter bekerja secara kolaboratif dengan penjelasan hubungan dari kelas (anak) lainnya untuk membuat pemetaan baik melalui tabel gabungan atau dengan membuat kolom kunci asing di tabel terkait dari entitas pemilik.Untuk menggambarkan cara
MapppedBy
kerjanya, pertimbangkan kode di bawah ini. JikaMappedBy
parameter dihapus, maka Hibernate sebenarnya akan membuat DUA tabel bergabung! Mengapa? Karena ada simetri dalam hubungan banyak ke banyak dan Hibernate tidak memiliki alasan untuk memilih satu arah di atas yang lain.Karena itu kami gunakan
MappedBy
untuk memberi tahu Hibernate, kami telah memilih entitas lain untuk menentukan pemetaan hubungan antara dua entitas.Menambahkan @JoinColumn (nama = "driverID") di kelas pemilik (lihat di bawah), akan mencegah pembuatan tabel bergabung dan sebagai gantinya, membuat kolom kunci asing driverID di tabel Mobil untuk membuat pemetaan:
sumber
JPA adalah API berlapis, level yang berbeda memiliki anotasi sendiri. Level tertinggi adalah (1) Level entitas yang menggambarkan kelas persisten, maka Anda memiliki (2) level database relasional yang menganggap entitas dipetakan ke database relasional dan (3) model java.
Level 1 anotasi:
@Entity
,@Id
,@OneToOne
,@OneToMany
,@ManyToOne
,@ManyToMany
. Anda dapat memperkenalkan kegigihan dalam aplikasi Anda menggunakan anotasi tingkat tinggi ini sendirian. Tapi kemudian Anda harus membuat database Anda sesuai dengan asumsi yang dibuat JPA. Anotasi ini menentukan entitas / model hubungan.Level 2 penjelasan:
@Table
,@Column
,@JoinColumn
, ... Mempengaruhi pemetaan dari entitas / properti untuk tabel database relasional / kolom jika Anda tidak puas dengan default JPA atau jika Anda perlu untuk memetakan ke database yang sudah ada. Anotasi ini dapat dilihat sebagai anotasi implementasi, mereka menentukan bagaimana pemetaan harus dilakukan.Menurut pendapat saya yang terbaik adalah tetap menempel sebanyak mungkin pada anotasi tingkat tinggi dan kemudian memperkenalkan anotasi tingkat rendah sesuai kebutuhan.
Untuk menjawab pertanyaan:
@OneToMany
/mappedBy
adalah yang terbaik karena hanya menggunakan anotasi dari domain entitas. The@oneToMany
/@JoinColumn
juga baik-baik saja tetapi menggunakan anotasi implementasi di mana ini tidak sepenuhnya diperlukan.sumber
Biarkan saya membuatnya sederhana.
Anda dapat menggunakan @JoinColumn di kedua sisi terlepas dari pemetaan.
Mari kita bagi menjadi tiga kasus.
1) Pemetaan dua arah dari Cabang ke Perusahaan.
2) Pemetaan dua arah dari Perusahaan ke Cabang.
3) Hanya pemetaan dua arah dari Perusahaan ke Cabang.
Jadi setiap kasus penggunaan akan termasuk dalam tiga kategori ini. Jadi izinkan saya menjelaskan bagaimana cara menggunakan @JoinColumn dan mappedBy .
1) Pemetaan dua arah dari Cabang ke Perusahaan.
Gunakan JoinColumn di tabel Cabang.
2) Pemetaan dua arah dari Perusahaan ke Cabang.
Gunakan mappedBy di tabel Company seperti dijelaskan oleh jawaban @Mykhaylo Adamovych.
3) Pemetaan dua arah dari Perusahaan ke Cabang.
Cukup gunakan @JoinColumn di tabel Perusahaan.
Ini mengatakan bahwa berdasarkan pemetaan "keyId" kunci asing di tabel cabang, dapatkan saya daftar semua cabang. CATATAN: Anda tidak dapat mengambil perusahaan dari cabang dalam kasus ini, hanya pemetaan uni-directional yang ada dari perusahaan ke cabang.
sumber