Saya mendapatkan pengecualian berikut:
Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
at sei.persistence.wf.entities.Element_$$_jvstc68_47.getNote(Element_$$_jvstc68_47.java)
at JSON_to_XML.createBpmnRepresantation(JSON_to_XML.java:139)
at JSON_to_XML.main(JSON_to_XML.java:84)
ketika saya mencoba menelepon dari saluran utama berikut:
Model subProcessModel = getModelByModelGroup(1112);
System.out.println(subProcessModel.getElement().getNote());
Saya menerapkan getModelByModelGroup(int modelgroupid)
metode pertama seperti ini:
public static Model getModelByModelGroup(int modelGroupId, boolean openTransaction) {
Session session = SessionFactoryHelper.getSessionFactory().getCurrentSession();
Transaction tx = null;
if (openTransaction) {
tx = session.getTransaction();
}
String responseMessage = "";
try {
if (openTransaction) {
tx.begin();
}
Query query = session.createQuery("from Model where modelGroup.id = :modelGroupId");
query.setParameter("modelGroupId", modelGroupId);
List<Model> modelList = (List<Model>)query.list();
Model model = null;
for (Model m : modelList) {
if (m.getModelType().getId() == 3) {
model = m;
break;
}
}
if (model == null) {
Object[] arrModels = modelList.toArray();
if (arrModels.length == 0) {
throw new Exception("Non esiste ");
}
model = (Model)arrModels[0];
}
if (openTransaction) {
tx.commit();
}
return model;
} catch(Exception ex) {
if (openTransaction) {
tx.rollback();
}
ex.printStackTrace();
if (responseMessage.compareTo("") == 0) {
responseMessage = "Error" + ex.getMessage();
}
return null;
}
}
dan mendapat pengecualian. Kemudian seorang teman menyarankan saya untuk selalu menguji sesi dan mendapatkan sesi saat ini untuk menghindari kesalahan ini. Jadi saya melakukan ini:
public static Model getModelByModelGroup(int modelGroupId) {
Session session = null;
boolean openSession = session == null;
Transaction tx = null;
if (openSession) {
session = SessionFactoryHelper.getSessionFactory().getCurrentSession();
tx = session.getTransaction();
}
String responseMessage = "";
try {
if (openSession) {
tx.begin();
}
Query query = session.createQuery("from Model where modelGroup.id = :modelGroupId");
query.setParameter("modelGroupId", modelGroupId);
List<Model> modelList = (List<Model>)query.list();
Model model = null;
for (Model m : modelList) {
if (m.getModelType().getId() == 3) {
model = m;
break;
}
}
if (model == null) {
Object[] arrModels = modelList.toArray();
if (arrModels.length == 0) {
throw new RuntimeException("Non esiste");
}
model = (Model)arrModels[0];
if (openSession) {
tx.commit();
}
return model;
} catch(RuntimeException ex) {
if (openSession) {
tx.rollback();
}
ex.printStackTrace();
if (responseMessage.compareTo("") == 0) {
responseMessage = "Error" + ex.getMessage();
}
return null;
}
}
}
tapi tetap saja, dapatkan error yang sama. Saya telah membaca banyak untuk kesalahan ini dan menemukan beberapa solusi yang mungkin. Salah satunya adalah untuk mengatur lazyLoad ke false, tetapi saya tidak diizinkan untuk melakukan ini itu sebabnya saya disarankan untuk mengontrol sesi
Jika Anda menggunakan Spring tandai kelas sebagai @Transaksional , maka Spring akan menangani manajemen sesi.
Dengan menggunakan
@Transactional
, banyak aspek penting seperti propagasi transaksi ditangani secara otomatis. Dalam hal ini jika metode transaksional lain disebut metode akan memiliki opsi untuk bergabung dengan transaksi yang sedang berlangsung menghindari pengecualian "tidak ada sesi".PERINGATAN Jika Anda menggunakannya
@Transactional
, harap perhatikan perilaku yang dihasilkan. Lihat artikel ini untuk perangkap umum. Misalnya, pembaruan untuk entitas tetap ada meskipun Anda tidak secara eksplisit meneleponsave
sumber
@EnableTransactionManagement
konfigurasi Anda untuk memungkinkan transaksi. " jika metode transaksional lain disebut metode akan memiliki opsi untuk bergabung dengan transaksi yang sedang berlangsung " perilaku ini berbeda untuk cara transaksi yang berbeda diimplementasikan, yaitu antarmuka proxy vs proxy kelas atau tenun AspectJ. Lihat dokumentasi .Transactional
anotasi Spring dengan demikian disarankan, tidak hanya untuk memodifikasi transaksi, tetapi juga untuk mengakses hanya yang?Anda dapat mencoba mengatur
di hibernate.cfg.xml atau persistence.xml
Masalah yang perlu diingat dengan properti ini dijelaskan dengan baik di sini
sumber
<property name="hibernate.enable_lazy_load_no_trans" value="true"/>
hibernate.enable_lazy_load_no_trans
adalah Anti-Pola , bukan?Cara terbaik untuk mengatasinya
LazyInitializationException
adalah dengan menggunakanJOIN FETCH
arahan:Pokoknya, JANGAN gunakan Anti-Pola berikut seperti yang disarankan oleh beberapa jawaban:
hibernate.enable_lazy_load_no_trans
Terkadang, proyeksi DTO adalah pilihan yang lebih baik daripada mengambil entitas, dan dengan cara ini, Anda tidak akan mendapatkannya
LazyInitializationException
.sumber
FetchType=EAGER
, tetapi ini bukan solusi yang tepat, bukan?@Transactional
layanan.Saya mendapatkan kesalahan yang sama untuk hubungan satu ke banyak untuk penjelasan di bawah ini.
Diubah seperti di bawah ini setelah menambahkan fetch = FetchType.EAGER, itu berhasil untuk saya.
sumber
jika Anda menggunakan pegas data jpa, pegas boot Anda dapat menambahkan baris ini di application.properties
sumber
Pengecualian ini karena saat Anda menelepon
session.getEntityById()
, sesi akan ditutup. Jadi, Anda perlu melampirkan kembali entitas ke sesi. Atau solusi Easy hanya mengkonfigurasidefault-lazy="false"
untuk Andaentity.hbm.xml
atau jika Anda menggunakan anotasi tambahkan saja@Proxy(lazy=false)
ke kelas entitas Anda.sumber
Saya mengalami masalah yang sama. Saya pikir cara lain untuk memperbaikinya adalah Anda dapat mengubah kueri untuk bergabung mengambil Elemen dari Model sebagai berikut:
sumber
Ini berarti bahwa objek yang Anda coba akses tidak dimuat, jadi tulislah kueri yang membuat gabungan ambil dari objek yang Anda coba akses.
Misalnya:
Jika Anda mencoba untuk mendapatkan ObjectB dari ObjectA di mana ObjectB adalah kunci asing di ObjectA.
Pertanyaan:
sumber
Ada beberapa jawaban bagus di sini yang menangani kesalahan ini dalam cakupan luas. Saya mengalami situasi tertentu dengan Spring Security yang memiliki perbaikan cepat, meskipun mungkin tidak optimal.
Selama otorisasi pengguna (segera setelah masuk dan melewati otentikasi) saya menguji entitas pengguna untuk otoritas tertentu di kelas kustom yang memperluas SimpleUrlAuthenticationSuccessHandler.
Entitas pengguna saya mengimplementasikan UserDetails dan memiliki seperangkat Peran yang dimuat malas yang melemparkan "org.hibernate.LazyInitializationException - tidak dapat menginisialisasi proxy - tidak ada Sesi" pengecualian. Mengubah Set itu dari "fetch = FetchType.LAZY" menjadi "fetch = FetchType.EAGER" memperbaiki ini untuk saya.
sumber
Jika Anda menggunakan JPQL, gunakan JOIN FETCH adalah cara termudah: http://www.objectdb.com/java/jpa/query/jpql/from#LEFT_OUTER_INNER_JOIN_FETCH_
sumber
Menghadapi Pengecualian yang sama dalam berbagai kasus penggunaan.
Use Case: Cobalah membaca data dari DB dengan proyeksi DTO.
Solusi: Gunakan metode get alih-alih memuat .
Operasi Generik
}
Kelas Kegigihan
Antarmuka CustomerDAO
Kelas Obyek Transfer Entitas
}
Kelas Pabrik
}
DAO spesifik entitas
}
Mengambil data: Kelas Tes
Sajikan Data
Permintaan dan output yang dihasilkan oleh Sistem Hibernate
Hibernate: pilih customer0_.Id sebagai Id1_0_0_, customer0_.City sebagai City2_0_0_, customer0_.Name as Name3_0_0_ dari CustomerLab31 customer0_ di mana customer0_.Id =?
Nama Pelanggan -> Cody, CustomerCity -> LA
sumber
Jika Anda menggunakan
Grail's
Framework, mudah untuk menyelesaikan pengecualian inisialisasi malas dengan menggunakanLazy
kata kunci pada bidang tertentu di Kelas Domain.Sebagai contoh:
Temukan informasi lebih lanjut di sini
sumber
Dalam kasus saya, kesalahan penempatan
session.clear()
menyebabkan masalah ini.sumber
Ini berarti Anda menggunakan JPA atau hibernasi dalam kode Anda dan melakukan operasi modifikasi pada DB tanpa melakukan transaksi logika bisnis. Jadi solusi sederhana untuk ini adalah tandai sepotong kode Anda @Transaksional
sumber
menggunakan session.get (*. class, id); tapi jangan memuat fungsinya
sumber
Anda juga bisa menyelesaikannya dengan menambahkan lazy = false ke dalam file * .hbm.xml Anda atau Anda dapat memasukkan objek Anda di Hibernate.init (Objek) ketika Anda mendapatkan objek dari db
sumber
Lakukan perubahan berikut pada servlet-context.xml
sumber