Apakah pemuatan malas di Hibernate?

178

Apa itu pemuatan malas di Jawa? Saya tidak mengerti prosesnya. Adakah yang bisa membantu saya untuk memahami proses pemuatan malas?

kursi goyang
sumber

Jawaban:

268

Katakanlah Anda memiliki orang tua dan orang tua itu memiliki koleksi anak-anak. Hibernate sekarang dapat "memuat-malas" anak-anak, yang artinya tidak memuat semua anak saat memuat orang tua. Sebaliknya, itu memuat mereka ketika diminta untuk melakukannya. Anda dapat meminta ini secara eksplisit atau, dan ini jauh lebih umum, hibernate akan memuatnya secara otomatis ketika Anda mencoba mengakses anak.

Pemuatan malas dapat membantu meningkatkan kinerja secara signifikan karena seringkali Anda tidak membutuhkan anak-anak sehingga mereka tidak akan dimuat.

Waspadalah terhadap n + 1-masalah. Hibernate tidak akan memuat semua anak saat Anda mengakses koleksi. Sebaliknya, itu akan memuat setiap anak secara individual. Saat mengulangi koleksi, ini menyebabkan kueri untuk setiap anak. Untuk menghindari hal ini, Anda dapat mengelabui hibernate agar memuat semua anak secara bersamaan, misalnya dengan memanggil parent.getChildren (). Size ().

Thomas Lötzer
sumber
5
Atau Hibernate.initialize (parent.getChildren ()) harus digunakan
HakunaMatata
18
Pernyataan "ketika Anda mengakses koleksi ... itu akan memuat setiap anak secara individual" sebenarnya sama sekali tidak akurat. Sebenarnya justru sebaliknya. Setiap dereference dari parent.getChildren () akan menyebabkan Hibernate memuat semua anak dalam koleksi dalam satu permintaan db. Kecuali jika Anda menggunakan petunjuk pemuatan malas "ekstra malas" yang sangat istimewa. Atau kecuali Anda menyimpan koleksi di cache tingkat kedua dan anak-anak yang terkait tidak juga di-cache.
Steve Ebersole
Oh, Stack Overflow - jawaban terbaik dapat ditemukan di bagian bawah halaman ;-)
Piotrek Hryciuk
76

"Pemuatan malas" berarti bahwa suatu entitas akan dimuat hanya ketika Anda benar-benar mengakses entitas untuk pertama kalinya.

The Pola seperti ini:

public Entity getEntity() {
    if (entity == null) {
        entity = loadEntity();
    }
    return entity;
}

Ini menghemat biaya preloading / prefilling semua entitas dalam dataset besar sebelumnya sementara Anda sebenarnya tidak membutuhkan semuanya .

Di Hibernate, Anda dapat mengonfigurasi untuk dengan malas memuat koleksi entitas anak. The aktual lazy loading kemudian dilakukan di dalam metode dari PersistentSetyang menggunakan Hibernate "di bawah kerudung" untuk menetapkan koleksi entitas sebagai Set.

Misalnya

public class Parent {
    private Set<Child> children;

    public Set<Child> getChildren() {
        return children;
    }
}

.

public void doSomething() {
    Set<Child> children = parent.getChildren(); // Still contains nothing.

    // Whenever you call one of the following (indirectly), 
    // Hibernate will start to actually load and fill the set.
    children.size();
    children.iterator();
}
BalusC
sumber
25

Martin Fowler mendefinisikan pola Beban Malas dalam Pola Arsitektur Aplikasi Perusahaan seperti:

Objek yang tidak berisi semua data yang Anda butuhkan tetapi tahu cara mendapatkannya.

Jadi, ketika memuat objek yang diberikan, idenya adalah untuk tidak bersemangat memuat objek terkait yang tidak dapat Anda gunakan segera untuk menghemat biaya kinerja terkait. Sebaliknya, objek terkait hanya akan dimuat saat digunakan.

Ini bukan pola khusus untuk akses data dan Hibernate tetapi sangat berguna dalam bidang tersebut dan Hibernate mendukung pemuatan malas dari asosiasi satu-ke-banyak dan asosiasi satu titik (satu-ke-satu dan banyak-ke-satu) juga dalam kondisi tertentu. Interaksi malas dibahas secara lebih rinci dalam Bab 19 dari Dokumentasi Referensi Hibernate 3.0.

Thivent Pascal
sumber
15

Pemuatan malas Bydefault benar. Pemuatan malas berarti ketika kueri pemilihan dijalankan, itu tidak akan mengenai basis data. Ini akan menunggu fungsi getter yaitu ketika kita diminta, itu akan diambil dari basis data. misalnya: Anda adalah orang tua yang memiliki anak dengan banyak mainan. Tetapi masalah saat ini adalah setiap kali Anda memanggilnya (kami menganggap Anda memiliki anak laki-laki), dia datang kepada Anda dengan semua mainannya juga. Sekarang ini adalah masalah karena Anda tidak ingin dia membawa mainannya sepanjang waktu. Jadi sebagai orang tua yang rasional, Anda langsung saja mendefinisikan mainan anak-anak sebagai LAZY. Sekarang setiap kali Anda memanggilnya, dia hanya mendatangi Anda tanpa mainannya.

Chandresh Solanki
sumber
11

Malas mengambil memutuskan apakah akan memuat objek anak saat memuat Objek Induk. Anda perlu melakukan pengaturan ini masing-masing file pemetaan hibernate kelas induk. Lazy = true(Berarti tidak memuat anak) Secara default pemuatan malas objek anak adalah benar.

Ini memastikan bahwa objek anak tidak dimuat kecuali mereka secara eksplisit dipanggil dalam aplikasi dengan memanggil getChild()metode pada orang tua. Dalam hal ini hibernate mengeluarkan panggilan database baru untuk memuat anak ketika getChild()secara aktif dipanggil pada objek Induk.

Tetapi dalam beberapa kasus Anda perlu memuat objek anak ketika orang tua dimuat. Buat saja lazy = false dan hibernate akan memuat anak ketika orang tua dimuat dari database.

Contoh: Jika Anda punya TABEL? KARYAWAN dipetakan ke objek Karyawan dan berisi sekumpulan objek Alamat. Kelas Induk: Kelas karyawan, Kelas anak: Kelas Alamat

public class Employee { 
private Set address = new HashSet(); // contains set of child Address objects 
public Set getAddress () { 
return address; 
} 
public void setAddresss(Set address) { 
this. address = address; 
} 
} 

Dalam file Employee.hbm.xml

<set name="address" inverse="true" cascade="delete" lazy="false"> 
<key column="a_id" /> 
<one-to-many class="beans Address"/> 
</set> 

Dalam konfigurasi di atas. Jika lazy="false": - ketika Anda memuat objek Karyawan, waktu itu, objek objek anak juga dimuat dan ditetapkan ke metode setAddresss (). Jika Anda memanggil employee.getAdress () kemudian memuat pengembalian data. Tidak ada panggilan database baru.

Jika lazy="true": - Ini konfigurasi default. Jika Anda tidak menyebutkan maka hibernasi pertimbangkan lazy = true. ketika Anda memuat objek Karyawan waktu itu objek anak Alamat tidak dimuat. Anda perlu panggilan tambahan ke basis data untuk mendapatkan objek alamat. Jika Anda memanggil employee.getAdress()maka saat itu permintaan basis data akan menyala dan mengembalikan hasil. Panggilan basis data baru.

Bhavin Shah
sumber
Karyawan dan Alamat tidak memiliki hubungan Orangtua-Anak dalam skenario ini. Itu adalah hubungan 'has-a' !
Ram
Ini adalah agregasi, bukan warisan.
Rishi
11

Dalam bahasa awam, rasanya seperti Anda membuat kue dan Anda membutuhkan 5-10 bahan dari kulkas. Anda memiliki dua pilihan, dapatkan semua bahan dari lemari es dan letakkan di platform dapur Anda, atau bawa barang yang Anda inginkan saat dibutuhkan.

Demikian pula, dalam pemuatan cepat, Anda mengambil semua informasi tentang kacang dan kelas terkait (bukan anak-anak atau hubungan-tetapi memiliki hubungan, yaitu kue memiliki tepung, susu, krim dll), dan dalam hal pemuatan malas, pertama Anda hanya membawa pengenal dan nilai-nilai yang berasal dari tabel yang sama (bahan-bahan penting yang pertama-tama Anda perlukan dalam mangkuk Anda untuk kue). Semua informasi yang berasal dari tabel lain akan diambil seperti dan ketika diperlukan / digunakan.

Keyur
sumber
8

Pemuatan Malas? Yah, itu hanya berarti bahwa catatan anak tidak diambil segera, tetapi secara otomatis segera setelah Anda mencoba mengaksesnya.

Steffen
sumber
3

Pengaturan malas memutuskan apakah akan memuat objek anak saat memuat Objek Induk. Anda harus melakukan pengaturan ini masing-masing file pemetaan hibernate dari kelas induk. Lazy = true (berarti tidak memuat anak) Secara default, malas memuat objek anak adalah benar . Ini memastikan bahwa objek anak tidak dimuat kecuali mereka secara eksplisit dipanggil dalam aplikasi dengan memanggil metode getChild () pada orang tua. Dalam hal ini hibernate mengeluarkan panggilan database baru untuk memuat anak ketika getChild () diaktifkan secara aktif pada Parent objek.Tapi dalam beberapa kasus Anda perlu memuat objek anak ketika orang tua dimuat. Jadikan saja lazy = false dan hibernate akan memuat anak ketika orang tua dimuat dari database. Exampleslazy = true (default) Address child dari kelas Pengguna dapat dibuat malas jika tidak sering dibutuhkan.

Siva Chimpiri
sumber
3

Pemuatan malas memungkinkan Anda untuk menunda pengambilan asosiasi atau memiliki kontrol yang lebih baik atas strategi pengambilan.

Saat Anda menggunakan pemuatan EAGER, Anda menetapkan rencana pengambilan global yang tidak dapat ditimpa pada waktu kueri, artinya Anda terbatas pada keputusan yang Anda ambil saat mendesain model entitas Anda. Pengambilan EAGER adalah bau kode , karena strategi pengambilan adalah kebijakan waktu permintaan dan mungkin berbeda dari kasus penggunaan bisnis ke yang lain.

The strategi pengambilan adalah aspek yang sangat penting, karena terlalu banyak pengambilan BERSEMANGAT dapat menyebabkan kinerja terkait masalah serius.

Vlad Mihalcea
sumber
2

Pemuatan malas adalah pola desain yang biasa digunakan dalam pemrograman komputer untuk menunda inisialisasi suatu objek sampai pada titik dibutuhkannya. Ini dapat berkontribusi pada efisiensi dalam operasi program jika digunakan dengan benar dan tepat

Wikipedia

Tautan Lazy Memuat dari hibernate.org

Diego Dias
sumber
1

Yah itu hanya berarti memuat data yang Anda butuhkan saat ini daripada memuat sejumlah data sekaligus yang tidak akan Anda gunakan sekarang. Dengan demikian membuat waktu buka aplikasi lebih cepat dari biasanya.

Abhinaya Pandey
sumber
0

Hiberante mendukung fitur inisialisasi malas untuk entitas dan koleksi. Mesin berhibernasi hanya memuat objek yang kami tanyakan tidak ada hal lain atau koleksi.

lazy = "false" secara default memuat inisialisasi menyebutkan untuk satu-satunya anak adalah lazy.dalam kasus true yang orangtua memuat tidak mendukung anak

abburi
sumber
0

Pengaturan malas memutuskan apakah akan memuat objek anak saat memuat Objek Induk. Anda harus melakukan pengaturan ini masing-masing file pemetaan hibernate dari kelas induk. Lazy = true (berarti tidak memuat anak) Secara default, malas memuat objek anak adalah benar .

Manikandan Adhimoolam
sumber
0

Anehnya, tidak ada jawaban yang berbicara tentang bagaimana hal itu dicapai dengan hibernasi di belakang layar.

Pemuatan malas adalah pola desain yang secara efektif digunakan dalam hibernasi untuk alasan kinerja yang melibatkan teknik berikut.


1. Instrumentasi kode byte :

Meningkatkan definisi kelas dasar dengan kait hibernasi untuk mencegat semua panggilan ke objek entitas itu.

Dilakukan baik pada waktu kompilasi atau menjalankan waktu [memuat]

1.1 Waktu kompilasi

  • Operasi waktu pasca kompilasi

  • Sebagian besar oleh plugin pakar / semut

1.2 Jalankan waktu

  • Jika tidak ada instrumentasi waktu kompilasi yang dilakukan, ini dibuat pada saat run time Menggunakan perpustakaan seperti javassist

2. Proxy

Objek entitas yang dikembalikan Hibernate adalah proksi dari tipe nyata.

Lihat juga: Javassist. Apa ide utama dan di mana penggunaan sebenarnya?

Sankarganesh Eswaran
sumber