Proxy dalam metode Hibernate load ()

1. Ikhtisar

Dalam tutorial ini, kita akan melihat apa itu proxy dalam konteks metode load () Hibernate .

Untuk pembaca yang baru mengenal Hibernate, pertimbangkan untuk mempelajari dasar-dasarnya terlebih dahulu.

2. Pengantar Singkat Untuk Proksi dan Metode load ()

Menurut definisi, proxy adalah "fungsi yang diberi wewenang untuk bertindak sebagai wakil atau pengganti yang lain" .

Ini berlaku untuk Hibernate saat kita memanggil Session.load () untuk membuat apa yang disebut proxy yang tidak diinisialisasi dari kelas entitas yang kita inginkan.

Sederhananya, Hibernate membuat subkelas kelas entitas kami, menggunakan perpustakaan CGLib . Selain metode @Id , implementasi proxy mendelegasikan semua metode properti lainnya ke sesi Hibernate untuk mengisi instance, seperti:

public class HibernateProxy extends MyEntity {     private MyEntity target;     public String getFirstName() {         if (target == null) {             target = readFromDatabase();         }         return target.getFirstName();     } }

Subclass ini akan menjadi subclass yang dikembalikan alih-alih menanyakan database secara langsung.

Setelah salah satu metode entitas dipanggil, entitas dimuat dan pada saat itu menjadi proxy yang diinisialisasi.

3. Proksi dan pemuatan lambat

3.1. Entitas Tunggal

Mari kita pikirkan tentang Karyawan sebagai suatu entitas. Untuk memulai, kita akan berasumsi bahwa itu tidak ada hubungannya dengan tabel lain.

Jika kita menggunakan Session.load () untuk membuat instance Karyawan :

Employee albert = session.load(Employee.class, new Long(1));

Kemudian Hibernate akan membuat proxy Karyawan yang tidak diinisialisasi . Ini akan berisi ID yang kami berikan tetapi sebaliknya tidak akan memiliki nilai lain karena kami belum mencapai database.

Namun, setelah kami memanggil metode di albert :

String firstName = albert.getFirstName();

Kemudian Hibernate akan menanyakan tabel database karyawan untuk entitas dengan kunci utama 1, mengisi albert dengan propertinya dari baris yang sesuai.

Jika gagal menemukan baris, Hibernate akan melempar ObjectNotFoundException .

3.2. Hubungan Satu ke Banyak

Sekarang, mari kita buat entitas Perusahaan juga, di mana Perusahaan memiliki banyak Karyawan:

public class Company {     private String name;     private Set employees; }

Jika kali ini kita menggunakan Session.load () di perusahaan:

Company bizco = session.load(Company.class, new Long(1)); String name = bizco.getName();

Kemudian properti perusahaan diisi seperti sebelumnya, kecuali kumpulan karyawan yang sedikit berbeda.

Lihat, kami hanya menanyakan baris perusahaan, tetapi proxy akan membiarkan karyawan disetel sendiri sampai kami memanggil getEmployees tergantung pada strategi pengambilan.

3.3. Hubungan Banyak-ke-Satu

Kasusnya serupa dengan arah yang berlawanan:

public class Employee {     private String firstName;     private Company workplace; }

Jika kita menggunakan load () lagi:

Employee bob = session.load(Employee.class, new Long(2)); String firstName = bob.getFirstName();

bob sekarang akan diinisialisasi, dan sebenarnya, tempat kerja sekarang akan disetel menjadi proxy yang tidak diinisialisasi tergantung pada strategi pengambilan.

4. Lazy-ish Loading

Sekarang, load () tidak akan selalu memberi kita proxy yang tidak diinisialisasi. Faktanya, dokumen java Sesi mengingatkan kita (penekanan ditambahkan):

Metode ini mungkin mengembalikan instance proksi yang diinisialisasi sesuai permintaan, ketika metode non-identifier diakses.

Contoh sederhana kapan ini bisa terjadi adalah dengan ukuran batch.

Katakanlah kita menggunakan @BatchSize di entitas Karyawan kita :

@Entity @BatchSize(size=5) class Employee { // ... }

Dan kali ini kami memiliki tiga karyawan:

Employee catherine = session.load(Employee.class, new Long(3)); Employee darrell = session.load(Employee.class, new Long(4)); Employee emma = session.load(Employee.class, new Long(5));

Jika kita menelepon getFirstName di catherine :

String cathy = catherine.getFirstName();

Kemudian, sebenarnya, Hibernate dapat memutuskan untuk memuat ketiga karyawan sekaligus, mengubah ketiganya menjadi proxy yang diinisialisasi.

Dan kemudian, saat kita memanggil nama depan darrell :

String darrell = darrell.getFirstName();

Then Hibernate doesn't hit the database at all.

5. Eager Loading

5.1. Using get()

We can also bypass proxies entirely and ask Hibernate to load the real thing using Session.get():

Employee finnigan = session.get(Employee.class, new Long(6));

This will call the database right away, instead of returning a proxy.

And actually, instead of an ObjectNotFoundException, it will return null if finnigan doesn't exist.

5.2. Performance Implications

While get() is convenient, load() can be lighter on the database.

For instance, let's say gerald is going to work for a new company:

Employee gerald = session.get(Employee.class, new Long(7)); Company worldco = (Company) session.load(Company.class, new Long(2)); employee.setCompany(worldco); session.save(employee);

Karena kita tahu bahwa kita hanya akan mengubah catatan karyawan dalam situasi ini , memanggil load () untuk Perusahaan adalah bijaksana.

Jika kita memanggil get () di Perusahaan , maka kita akan memuat semua datanya tanpa perlu dari database.

6. Kesimpulan

Dalam artikel ini, kami mempelajari secara singkat cara kerja proxy Hibernate dan bagaimana hal ini memengaruhi metode pemuatan dengan entitas dan hubungannya.

Juga, kami melihat sekilas bagaimana load () berbeda dari get ().

Seperti biasa, kode sumber lengkap yang menyertai tutorial tersedia di GitHub.