Selama Hibernate Session
, saya memuat beberapa objek dan beberapa di antaranya dimuat sebagai proxy karena pemuatan malas. Tidak apa-apa dan saya tidak ingin mematikan pemuatan malas.
Tetapi kemudian saya perlu mengirim beberapa objek (sebenarnya satu objek) ke klien GWT melalui RPC. Dan kebetulan objek konkret ini adalah proxy. Jadi saya perlu mengubahnya menjadi objek nyata. Saya tidak dapat menemukan metode seperti "terwujud" di Hibernate.
Bagaimana saya bisa mengubah beberapa objek dari proxy menjadi real dengan mengetahui kelas dan ID mereka?
Saat ini satu-satunya solusi yang saya lihat adalah mengusir objek dari cache Hibernate dan memuatnya kembali, tetapi itu benar-benar buruk karena banyak alasan.
HibernateProxy
mendefinisikanwriteReplace
metode untuk memaksa implementor melakukan sesuatu yang istimewa selama serialisasi.(T)Hibernate.unproxy(entity)
Seperti yang saya jelaskan dalam artikel ini , sejak Hibernate ORM 5.2.10 , Anda dapat melakukannya seperti ini:
Sebelum Hibernasi 5.2.10 . cara paling sederhana untuk melakukannya adalah dengan menggunakan metode unproxy yang ditawarkan oleh
PersistenceContext
implementasi internal Hibernate :sumber
Department
denganStudent
, apakah Anda masih perluunproxy(department.getStudents())
- atau cukupunproxy(department)
?PersistentContext#unproxy(proxy)
melempar pengecualian jika proxy tidak diinisialisasi sementaraHibernate.unproxy(proxy)
danLazyInitializer#getImplementation(proxy)
menginisialisasi proxy jika perlu. Hanya menangkap pengecualian karena perbedaan ini. ;-)Coba gunakan
Hibernate.getClass(obj)
sumber
Saya telah menulis kode berikut yang membersihkan objek dari proxy (jika belum diinisialisasi)
Saya menggunakan fungsi ini atas hasil layanan RPC saya (melalui aspek) dan membersihkan secara rekursif semua objek hasil dari proxy (jika tidak diinisialisasi).
sumber
Cara saya merekomendasikan dengan JPA 2:
sumber
Dengan Spring Data JPA dan Hibernate, saya menggunakan subinterfaces
JpaRepository
untuk mencari objek milik hierarki tipe yang dipetakan menggunakan strategi "join". Sayangnya, kueri mengembalikan proxy dari tipe dasar dan bukan contoh dari tipe beton yang diharapkan. Ini mencegah saya dari casting hasil ke tipe yang benar. Seperti Anda, saya datang ke sini mencari cara yang efektif untuk mendapatkan hak saya tidak diproksikan.Vlad memiliki ide yang tepat untuk tidak menguji hasil ini; Yannis memberikan sedikit lebih banyak detail. Menambah jawaban mereka, inilah yang mungkin Anda cari:
Kode berikut memberikan cara mudah untuk membatalkan proksi entitas proksi Anda:
Anda dapat memberikan Entitas yang tidak diproksi atau entitas yang diproksi ke
unproxy
metode. Jika mereka sudah tidak terbukti, mereka hanya akan dikembalikan. Jika tidak, mereka akan diproteksi dan dikembalikan.Semoga ini membantu!
sumber
Solusi lain adalah menelepon
Tepat sebelum menutup sesi.
sumber
Saya menemukan solusi untuk mendeproxy kelas menggunakan Java standar dan API JPA. Diuji dengan hibernate, tetapi tidak memerlukan hibernate sebagai dependensi dan harus bekerja dengan semua penyedia JPA.
Hanya satu persyaratan - perlu untuk memodifikasi kelas induk (Alamat) dan menambahkan metode pembantu sederhana.
Gagasan umum: tambahkan metode helper ke kelas induk yang mengembalikan sendiri. ketika metode dipanggil pada proxy, itu akan meneruskan panggilan ke instance nyata dan mengembalikan instance nyata ini.
Implementasi sedikit lebih kompleks, karena hibernate mengakui bahwa kelas proksi mengembalikan dirinya sendiri dan masih mengembalikan proksi alih-alih instance nyata. Solusinya adalah untuk membungkus instance yang dikembalikan ke dalam kelas wrapper sederhana, yang memiliki tipe kelas yang berbeda dari instance sebenarnya.
Dalam kode:
Untuk memberikan alamat proxy ke subkelas nyata, gunakan yang berikut ini:
sumber
Mulai dari Hiebrnate 5.2.10 Anda dapat menggunakan metode Hibernate.proxy untuk mengonversi proxy ke entitas Anda yang sebenarnya:
sumber
Terima kasih atas solusi yang disarankan! Sayangnya, tidak ada satupun yang berfungsi untuk kasus saya: menerima daftar objek CLOB dari database Oracle melalui JPA - Hibernate, menggunakan kueri asli.
Semua pendekatan yang diusulkan memberi saya baik ClassCastException atau hanya mengembalikan objek java Proxy (yang jauh di dalamnya berisi Clob yang diinginkan).
Jadi solusi saya adalah sebagai berikut (berdasarkan beberapa pendekatan di atas):
Semoga ini bisa membantu seseorang!
sumber