Hibernate çok tercih edilen ORM kütüphanlerinden biris. Kuşbakışı mimarisini
buradan aldım.
Her türlü XML dosyasında olduğu gibi hibernate konfigürasyonda dosyası da karmaşık gelebiliyor. Önemli bölümlerini göstern şekli
buradan aldım.
Bir diğer önemli konfigürasyon özelliği ise hibernate tarafından üretilen sql komutlarının gösterilebilmesi. Onun konfigürasyonunu gösteren şekli ise
buradan aldım. show_sql = true yapmak yeterli.
Hibernate ile iki kademeli önbellek kullanabilme imkanı da var. Yukarıdaki şekilde gösterilmediği için aşağıya
buradan aldığım bir şekil daha ekledim.
Session Factory:
Yaratılması pahalı bir nesne olup veritabanı başına bir tane yaratılmalıdır.
Session:
Veritabanına açılan kısa süreli bağlantılar gibidir. Bir session şu durumlarda bulunabilir.
Doğrudan Hibernate Kullanırken Session ve Transaction İlişkisi
Bir session nesnesinin ne olduğu ve transaction ile arasındaki ilişki
burada çok güzel anlatılmış.Burada unutulmaması gereken nokta session ve transactionlar birbirlerinden ayrılamaz ikililerdir.
Problemin özeti şu : JDBC ile veritabanına bağlantı açılması ile aslında transaction başlıyor. Ancak Hibernate default olarak bağlantının autocommit özelliğini false yapıyor. Daha sonra biz Hibernate ile session'ı kapatırsak transaction commit edilmeden bağlantıyı kapatıldığı için ne olacağı belirsiz.Transaction kullanılmadan sadece session açıp kapamanın neticesi
undefined (yani tanımsız, örneğin oracle için çalışırken başka bir veritabanı için çalışmayabilir) ve bu konuyu açıklayan güzel bir örnek te
burada var.
Dolayısıyla bir session nesnesinin açılıp kapatılması transaction'ının tamamlandığı anlamına
gelmiyor.
Yani bir session nesnesi alındıktan sonra illaki bir transaction nesnesi yaratıp, daha sonra commitTransaction() metodunu çağırmak gerekiyor. Aynı konuyu açıklayan bir diğer yazıyı ise
burada bulabilirsiniz.
Kullanım için örnek kodları
burada bulabilirsiniz.
Tüm bu detayları daha kolay hale getirmek için
Spring Framework ile gelen HibernateTemplate sınıfı da kullanılabilir.
Buradan aldığım şekilde de görüldüğü gibi HibernateTemplate
template tasarım örüntüsünü kullanır ve SessionFactory sınıfını kullanarak veritabanına erişimi sağlar.
Fikir olsun diye HibernateTemplate sınıfına SessionFactory sınıfının nasıl inject edilebileceğini gösteren bir şeklide
buradan aldım.
Aslında hemen hemen aynı mantıkta çalışan JDBCTemplate sınıfı da aşağıda. Aradaki tek fark hibernate için SessionFactory enjekte edilirken, JDBC için data source enjekte ediliyor.
Eğer Hibernate ile yüklenen bir nesne session kapatıldıktan sonra kullanılmaya kalkılırsa
hibernate LazyInitializationException atabilir. Burada da anlatıldığı gibi bazen hibernate ile yüklenen nesne yerine nesnenin princil anahtarını ve nesne sınıfını saklamak daha iyi olabilir.
Önbellek:
İki kademelidir. Aşağıda her iki belleği de anlatmaya çalıştım.
Birincil Önbellek
Bu konu için
Hibernate Birincil Önbellek başlıklı yazıya göz atabilirsiniz.
İkincil Önbellek
İkincil önbellekle ilgili kısmı
Hibernate ve İkincil Önbellek başlıklı yazıya taşıdım.
Nesnelerin Yönetilmesi
Hibernate nesnelerinin yönetilmesi
buradan aldığım şekilde gayet güzel açıklanmış.
Aynı şeyi anlatan bir başka şekli ise
burada buldum.
Nesnelerin Java veya hibernate kullanan başka bir dilden SQL'e çevirilmesi için hibernate bize bazı built-in type sınıfları sağlar. Bunları
burada buldum ve aşağıya ekledim.
SQL'e çevirilirken Hibernate bazı optimizasyonlar yapılmasına da imkan tanır. Örneğin buradan aldığım bir örnekte de açıklandığı gibi bazı veritabanlarındaki tablolar çok sayıda sutün ihtiva ederler. Bir nesnede yapılan küçük bir değişiklik bile kocaman bir SQL ile tüm satırların güncellenmesine sebep olabilir. Bu durumdan kurtulmak ve sadece değişen sutünlar için SQL üretilsin isteniyorsa
buradan aldığım örnekte de gösterildiği gibi sutünlarar dynamicInsert, dynamicUpdate özelliği atanabilir.
HQL
HQL için
HQL (Hibernate Query Language) başlıklı yazıya göz atabilirsiniz.
DAO ve Castle.ActiveRecord
Hibernate kullanırken izlenen iki tane temel yöntem var. İlki
Data Access Object (DAO), diğeri ise
ActiveRecord tasarım örüntüleri. ActiveRecord örüntüsünü gerçekleştiren kütüphanelerden birisi ise Caste ActiveRecord projesi.
Aşağıda iki yöntemi de kullanarak çizilmiş bir UML sınıf diagramı var.
Castle.ActiveRecord kullanırken sınıfımı ana bir ActiveRecordBase sınıfından türetmek yeterli.
DAO yönteminde ise her sınıfa karşılık bir de DAO sınıfı yazmak gerektiği için proje çok kalabalık hale geliyor. Aşağıdaki örneği
buradan aldım. BusinessObject TransferObject'i (yani yukarıdaki şekilde MyClass'a denk geliyor) veritabanına yazmak veya veritabanından okumak için DataAccessObject'i kullanmak zorunda.
Bu yüzden bence Castle.ActiveRecord, DAO'ya göre kullanması çok daha kolay olan bir yöntem.
ActiveRecord Session ve Transaction İlişkisi
Castle.ActiveRecord kullanılsa bile altta halen NHibernate kullanılmaya devam ettiği için yukarıda anlatılan session,transaction ilişkisi devam ediyor. Ancak Castle.ActiveRecord
buradan aldığım şu cümlede de anlatıldığı gibi transaction açma/kapama işlemini kendi hallediyor.
When ActiveRecord is about to delegate something to NHibernate it checks if there is a ISession instance available and if not, one is created and disposed as soon as the operation is completed.
Eğer transaction açma/kapama işlemi dışarıdan kontrol edilmek isteniyorsa ActiveRecord duruma SessionScope denilen bir sınıf ile çare
bulmuş.
Her iki durumu da açıklayan bir şekili aşağıda gösterdim.
Bir diğer fark ise Castle.ActiveRecord ile lazy loading false olarak başlıyor. Bu durumda şöyle açıklanmış.
All relation attributes (except BelongsTo) have a Lazy property that is false by default. You just need to enable Lazy along the same lines as described above.