Tolong bantu saya memahami di mana untuk penggunaan biasa BERGABUNG dan di mana JOIN FETCH.
Sebagai contoh, jika kita memiliki dua query
FROM Employee emp
JOIN emp.department dep
dan
FROM Employee emp
JOIN FETCH emp.department dep
Apakah ada perbedaan antara mereka? Jika ya, yang satu untuk digunakan kapan?
Dalam dua pertanyaan, anda menggunakan JOIN untuk query semua karyawan yang memiliki setidaknya satu departemen yang terkait.
Namun, perbedaannya adalah: pertama, permintaan anda akan kembali hanya Karyawan untuk Hibernate. Di kedua query, anda kembali Employes dan semua Departemen terkait.
Jadi, jika anda menggunakan query kedua, anda akan tidak perlu melakukan query baru untuk memukul database lagi untuk melihat Departemen masing-masing Karyawan.
Anda dapat menggunakan query kedua ketika anda yakin bahwa anda akan perlu Departemen masing-masing Karyawan. Jika anda tidak perlu Departemen, gunakan query pertama.
Saya merekomendasikan baca link ini jika anda perlu untuk menerapkan beberapa kondisi di MANA (apa yang anda mungkin akan perlu): https://stackoverflow.com/questions/5816417/how-to-properly-express-jpql-join-fetch-with-where-clause-as-jpa-2-criteriaq
Update
Jika anda don't menggunakan ambil
dan Departemen terus dikembalikan, karena pemetaan antara Karyawan dan Departemen (a @OneToMany
) adalah setted dengan FetchType.BERSEMANGAT
. Dalam hal ini, setiap HQL (dengan ambil
atau tidak) query dengan Karyawan
akan membawa semua Departemen. Ingat bahwa semua pemetaan *ToOne (@ManyToOne
dan @OneToOne
) yang BERSEMANGAT secara default.
di link ini yang saya sebutkan sebelumnya pada komentar, baca bagian ini :
"fetch" bergabung memungkinkan asosiasi atau koleksi nilai yang akan diinisialisasi bersama dengan orang tua mereka benda-benda dengan menggunakan satu pilih. Ini sangat berguna dalam kasus pengumpulan. Itu efektif menimpa outer join dan malas deklarasi file pemetaan untuk asosiasi dan koleksi.
ini "JOIN FETCH" akan's efek jika anda memiliki (fetch = FetchType.MALAS) properti untuk koleksi di dalam badan(contoh di bawah).
Dan hal ini hanya berpengaruh metode "ketika query harus terjadi". Dan anda juga harus tahu this:
hibernate memiliki dua orthogonal pengertian : kapan asosiasi diambil dan bagaimana itu diambil. Adalah penting bahwa anda tidak membingungkan mereka. Kami menggunakan ambil untuk menyempurnakan kinerja. Kita dapat menggunakan malas untuk mendefinisikan kontrak untuk data yang selalu tersedia di setiap terlepas contoh tertentu kelas.
saat ini asosiasi diambil --> anda "FETCH" jenis
cara itu diambil --> Bergabung/pilih/Subselect/Batch
Dalam kasus anda, MENGAMBIL hanya akan memiliki itu's efek jika anda memiliki departemen sebagaimana yang diatur di dalam Karyawan, sesuatu seperti ini dalam badan:
@OneToMany(fetch = FetchType.LAZY)
private Set<Department> department;
ketika anda menggunakan
FROM Employee emp
JOIN FETCH emp.department dep
anda akan mendapatkan emp
dan emp.dep
. ketika anda tidak menggunakan fetch anda masih bisa mendapatkan emp.dep
tapi hibernate akan pengolahan lain pilih ke database untuk mendapatkan yang ditetapkan departemen.
jadi hanya masalah tuning kinerja, tentang anda ingin mendapatkan semua hasil(anda perlu atau tidak) dalam satu query(bersemangat mengambil), atau anda ingin query terakhir ketika anda membutuhkannya(malas fetching).
Gunakan bersemangat mengambil ketika anda perlu untuk mendapatkan data kecil dengan satu pilih(satu query). Atau gunakan malas untuk mengambil query apa yang anda butuhkan terakhir(yang lebih kecil query).
gunakan ambil ketika :
tidak besar tidak dibutuhkan koleksi/diatur di dalam entitas tersebut anda akan mendapatkan
komunikasi dari server aplikasi untuk database server terlalu jauh dan perlu waktu lama
anda mungkin perlu bahwa koleksi terakhir ketika anda don't memiliki akses untuk itu(luar dari transaksional metode/kelas)
Jika anda memiliki @oneToOne pemetaan set untuk FetchType.MALAS dan anda menggunakan query kedua(karena anda perlu Departemen benda-benda untuk dimuat sebagai bagian dari Karyawan benda) apa Hibernate akan lakukan, itu akan mengeluarkan query untuk mengambil Jurusan benda-benda untuk setiap individu Karyawan objek menjemput dari DB. Kemudian pada kode yang mungkin anda akses Departemen benda melalui Pegawai Departemen-tunggal asosiasi dan Hibernate tidak akan mengeluarkan pertanyaan untuk mengambil Jurusan objek untuk diberikan Karyawan. Ingat Hibernate masih masalah permintaan sama dengan jumlah Karyawan itu telah diambil. Hibernate akan masalah yang sama jumlah permintaan di kedua atas pertanyaan jika anda ingin mengakses Departemen benda-benda dari semua Karyawan benda
Dherik : I'm tidak yakin tentang apa yang anda katakan, ketika anda don't menggunakan fetch hasilnya akan jenis : Daftar<Object[ ]>
yang berarti daftar Objek tabel dan daftar Pegawai.
Object[0] refers an Employee entity
Object[1] refers a Departement entity
Ketika anda menggunakan fetch, hanya ada satu pilih dan hasilnya adalah daftar Karyawan Daftar<Karyawan>
yang berisi daftar jurusan. Itu menimpa malas deklarasi entitas.