Hibernate.initialize() kullanımı-Java Uzmanı
Hibernate Session nesnesi, Entity objelerinin durumu persistent (kalıcı) olduğu durumlarda bu nesneleri veri tabanı ile ilişkilendirir. Yani persistent durumdaki bir Entity üzerinde yapılan her bir değişiklik veri tabanına güncellenir.
Bir Entity nesnesinin persistent duruma geçebilmesi için Session üzerinden get(), load(), save() ya da saveOrUpdate() metotlarından birinin çağrılmış olması gerekir.
Entity nesnesinin detached duruma gelmesi için Session nesnesinin flush edilmesi, kapatılması ve transaction’ın commitlenmesi gerekir.
Bir Entity nesnesi detached durumda iken bu nesnelerin saklandığı collection’a erişilmek istendiğinde Hibernate LazyInitializationException fırlatır.
Bazı durumlarda Collection’ların Session kapatılmadan önce yaratılması gerekir. Nesne yaratma işlemleri Entity objelerinin getter metotları çağrılarak yapılabilir. Örneğin bir personelin adresleri istendiğinde personel.getAdresler() bütün personel adreslerinin yaratılmasını sağlar. Kodu daha sonra okuyan yazılımcılar için bazen karmaşık ve generic kod yazımına elverişli olmayan bir durum ortaya çıkar.
Collection’ların lazy initialize yöntemiyle yaratılması için Hibernate.initialize() ve Hibernate.isInitialized() metotları yardımımıza koşar. Örneğin Session açık olduğu durumda Hibernate.initialize(personel) personelin proxy nesnesinin yaratılmasını zorlarken, Hibernate.initialize(personel.getAdresler()) benzer şekilde adres listesinin yaratılmasını sağlar.
Peki bu işi başka nasıl ele alabiliriz?
Session nesnesini kapatmamak da yöntemlerden biri. Fakat farklı katmanlarda kullanılan collection nesnelerinin Hibernate ile erişimlerinde Session’ın açık bırakılması sıkıntı yaratabilir. Kaynak yönetimi işin içinden çıkılmaz bir hal alabilir. Bu problemi çözmek için birkaç yöntemimiz var:
1. Web uygulamalarında bir filtre (Web Filter) tanımlanarak cevap istemciye dönerken Session nesnesini kapatabiliriz. Yalnız bu yöntemi uygulamamıza entegre ederken oluşabilecek hata durumlarını da düşünmeliyiz. Herhangi bir exception fırlatıldığında Session nesnesinin yine açık kalmaması gerekir. Görsel katmana cevabı döndürürken Session’ın kapatılmış Transaction’ın da mutlaka commitlenmiş olması gerekir.
2. Bazı uygulamalarda görsel katmanın ihtiyaç duyduğu collectionlar servis ya da iş katmanı dediğimiz katmanda oluşturularak istemciye döndürülür. Bu da iş katmanının bütün veriyi hazırlayarak sunuma hazır hale getirmesi anlamına gelir. Session kapatılmadan önce Hibernate.initialize() metodu görsel katmandan istenen her bir collection için çağrılır. Eğer fetch mode özelliği EAGER kullanılıyorsa buna gerek kalmaz.
Bu yöntem uygulama içinde Session Facade yerine Command Pattern kullanılıyorsa daha kolaydır.
3. Başka bir yöntem de yaratılmamış collection’lara ya da proxy nesnelere erişmek için yeni bir Session yaratarak merge() ve lock() metotları ile persistent objeleri birleştirmek. Hibernate bu işi otomatik olarak yapmaz. Zaten performans açısından da yapmamalıdır.
Eğer çok büyük boyuttaki collection nesnelerinin her bir kaydı yerine sadece bazı özelliklerine erişme ihtiyacınız varsa instance yaratmadan da sadece filtre ile bunu yapabilirsiniz. Örneğin büyük boyuttaki bir collection’ın eleman sayısına ;
((Integer) s.createFilter( collection, "select count(*)" ).list().get(0) ).intValue()
Sayfalama gibi özelliklerde kullanılan createFilter() metodu çok kullanışlıdır.
Kaynak : jboss.org