Hibernate “Lazy Initialization Exception” Nedir?
Hibernate’de iki nesneyi birbirine bağlamak için, iki yöntem kullanır. Bunlardan birincisi EAGER diğeri ise LAZY dir. Eğer EAGER kullanırsak nesneyi veritabanından çekerken EAGER olan tüm nesneleri de beraberinde çekeriz. Fakat LAZY kullanırsak, ihtiyaç duyduğumuzda ilgili veriler çekilecektir.
LAZY kullanımında bazı problemler olaşabilir. Bunlardan en yaygın olanı ise “lazy initialization exception” dır.
Bu problem nasıl ortaya çıkar?
Bir hibernate session (oturum) açılır ve ilgili nesne çekilir ve session’ı sonlandırırız. Eğer nesnenin LAZY olarak bağlı olduğu bir nesneye ulaşmaya çalışırsak bu durumda ilgili hatayı alırız.
Course.java
Student.java
Test.java
Çalıştırdığımızda konsolda aşağıdaki hatayı alırız.
Konsola bakıldığında “student” listesi çekiliyor ve sorunsuz olarak liste dolduruluyor. Daha sonra session sonlandırılıyor. Student nesnesindeki alanları kontrol ettiğimizde örnek olarak ad ve soyad, bu alanlar sorunsuz olarak görüntülenmektedir. “course” listesini çekmeye çalıştığımızda ise konsoldaki hatayı alırız. Çünkü session kapatılmıştır.
Bu hatayı üç şekilde çözebiliriz;
1) Fetch type LAZY yerine EAGER olarak tanımlanır. Bu problemi çözer fakat veri her çekildiğinde ilgili veriyi de çeker. Bu her zaman istediğimiz bir durum olmayabilir. Konsoldaki farklılığı incelemekte fayda olduğunu düşünüyorum.
Student listesini çektikten sonra, student_id ye göre course listesini de çekmektedir.
2) Session kapatılmadığı müddetçe ulaşılabilir.
Konsolu incelediğimizde session kapatılmadan önce course listesi doldurulduğu için session kapatıldıktan sonrada listeye ulaşabiliriz.
3) Eagerly Fetch uygulanır.
Yukarıdaki örnekte ise student nesnesini çekmeye çalıştığımızda course listesini join yaparak tek sorgu da alırız. Bu çözümün birinci çözüm ile farkı ise student nesnesindeki course fetch type LAZY dir. İstersek başka bir yerde join yapmayabiliriz.
