Multi-tenant uygulamaları kurumsal yazılım projelerinde hayata geçirmenin üç temel yolu vardır. Birinci yol her bir istemci
için tamamen ayrı bir fiziksel veritabanı kullanmaktır. Bu yaklaşımda JDBC veritabanı bağlantıları her bir istemci için
ayrı ayrı yönetilmektedir. Bu yönetim veritabanı bağlantı havuzları için de geçerlidir. Uygulamalar sisteme login olmuş
kullanıcıya ait tenant identifier ile aktif veritabanı bağlantı havuzunu seçerek faaliyet gösterirler.
İkinci yol ise fiziksel veritabanı düzeyinde ayırmak yerine her bir istemciyi birbirinden farklı şemalar ile ayırmaktır.
Bu yöntemin çalışabilmesi için ya JDBC veritabanı bağlantısının ya da bağlantı havuzunun parametre olarak tenant identifier
kabul etmesi gerekir. Bu durum söz konusu değil ise ALTER SESSION SET SCHEMA benzeri bir komut ile JDBC veritabanı
bağlantısının şema bilgisi değiştirilebilir.
Üçüncü yol ise bütün verinin tek bir şemada tutularak her bir istemci için ayrı tenant identifier değerlerinin
kullanılmasıdır. Bu yöntemde ortak bir şema ve bunun üzerindeki tablolar ile çalışılır. Veritabanı üzerinden çalıştırılacak
her bir sorguya tenant identifier kontrol ifadesi de eklenir. Hibernate ilk iki yöntemi 4.0 sürümü ile desteklerken,
üçüncü yöntem şu an için Hibernate 5’in bir özelliği olarak planlanmaktadır. Hibernate 4 öncesi dönemde bu özellik daha
önceki yazımızda da bahsettiğimiz gibi filter kabiliyeti ile hayata geçirilmektedir.
Hibernate 4 ile çalışırken öncelikle yapılması gereken konfigürasyon ayarlarında hibernate.multiTenancy attribute ile
hangi stratejinin kullanılacağını belirtmektir. Hali hazırda NONE, DATABASE, SCHEMA, DISCRIMINATOR değerleri
kullanılabilir, ancak aktif olarak sadece DATABASE ve SCHEMA değerleri desteklenmektedir. DATABASE ve SCHEMA
değerleri kullanıldığı vakit MultiTenantConnectionProvider arayüzünden implement edilen bir sınıfın da
hibernate.multi_tenant_connection_provider attribute değeri ile Hibernate’e tanıtılması gerekir. Bu sınıf içerisinde
basitçe tenant identifier değerine karşılık gelen veritabanı bağlantısı veya bağlantı havuzu dönülür. Eğer veritabanı
bağlantısı dönülürse bu bağlantının kullandığı şema bu sınıf içerisinde tenant identifier ile değiştirilmelidir.
hibernate.multi_tenant_connection_provider attribute’u yerine hibernate.connection.datasource attribute’unun
tanımlandığı durumda ise Hibernate DataSourceBasedMultiTenantConnectionProviderImpl sınıfından bir instance’ı
kullanarak JNDI’dan tenant identifier değerine karşılık gelen isimde bir datasource nesnesine lookup yapmaya
çalışmaktadır. Bu konfigürasyon detaylarından sonra uygulama içerisinde
sessionFactory.withOptions().tenantIdentifier("myTenantId").openSession();
benzeri bir ifade ile o andaki istemciye karşılık gelen bir tenant identifier ile Hibernate Session oluşturulabilir.
Eğer Hibernate 3 ile birlikte gelen contextual session kabiliyeti jta veya thread değerlerinden birisi ile devreye
alınmış ise bu durumda Hibernate’e sessionFactory.currentSession() metodu çağrıldığında hangi tenant identifier ile
Session oluşturması gerektiği söylenmelidir. Bunun için CurrentTenantIdentifierResolver arayüzünden implement edilmiş
bir sınıf kullanılabilir. Aktive edilmesi için hibernate.tenant_identifier_resolver konfigürasyon attribute değeri
olarak tanımlanması gerekir.