Hibernate 4.0 Ve Üstü Versiyonlarda Event Listener Ekleme

14-06-2014
Hibernate 4.0 versiyonundan sonra event listener ekleme yöntemi değişmiştir. Bu makelemizde Hibernate 4.0 versiyonu ve üst versiyonlarda event listener nasıl eklenir ondan bahsedeceğiz.

org.hibernate.integrator.spi.Integrator interface geliştiricilere SessionFactory üretilirken, yeni özelliklerin eklenmesi kolaylığı sağlar. Bu özelliklerden birisi de event listener eklemedir. Hibernate'in sağladığı bir servis org.hibernate.integrator.spi.Integrator interface'ini implement eden sınıfları, java.util.ServiceLoader mekanizmasını kullanarak bulur. Bu işlemin gerçekleşmesi için geliştiricilerin sadece META-INF/services/org.hibernate.integrator.spi.Integrator isimli bir dosya oluşturup, bu dosya içerisine org.hibernate.integrator.spi.Integrator interface'ini implement eden sınıfları paket adları ile beraber her satıra bir tane sınıf adı gelecek şekilde eklemeleri gerekmektedir.


Integrator Interface


public interface Integrator {
    /**
     * Perform integration.
     *
     * @param configuration The configuration used to create the session factory
     * @param sessionFactory The session factory being created
     * @param serviceRegistry The session factory's service registry
     */
    public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory, 
         SessionFactoryServiceRegistry serviceRegistry);
    
    /**
     * Tongue-in-cheek name for a shutdown callback.
     *
     * @param sessionFactory The session factory being closed.
     * @param serviceRegistry That session factory's service registry
     */
    public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry);
    
    /** 
     * Ignore this form!  Just do nothing in impl.  It uses the new metamodel api slated for completion in 5.0
     */
    public void integrate(MetadataImplementor metadata, SessionFactoryImplementor sessionFactory, 
                SessionFactoryServiceRegistry serviceRegistry );
}

integrate() metodu SessionFactory üretilirken, bu işleme dahil etmek istediğimiz işlemleri tanımlamayı sağlar. disintegrate() metodu ise SessionFactory kapatılırken yapılan işlemlere ek olarak yeni işlemlerin eklenmesini sağlar.


Event Listener Ekleme


Event listener eklemek için integrate() metodunu kullanacağız. Bu metodta dikkat edersek, serviceRegistery parametresi bulunmaktadır. Listener eklerken, bu parametrenin getService() metodunu kullanacağız.

Örnek:
public class MyIntegrator implements Integrator {
    public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory,
         SessionFactoryServiceRegistry serviceRegistry) {
    
        // EventListenerRegistry servisi cagriliyor. Bu servis araciligi ile listener eklenecek
        final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
            
         // EventListenerRegistry listener eklemek için 3 yol saglar:
        //  1) setListeners metodu ile var olan bir listener override edilir.
        eventListenerRegistry.setListeners( EventType.PRE_LOAD, new MyPreLoadFirstListener());
        //  2) event turune gore, listener zincirinin ilk halkasını olusturur.
        eventListenerRegistry.appendListeners( EventType.PRE_LOAD,  new MyPreLoadFirstListener());
    
        //  3) event turune gore, listener zincirinin son halkasını olusturur.
        eventListenerRegistry.appendListeners( EventType.PRE_LOAD,  new MyPreLoadSecondListener());
    }
    
    @Override
    public void integrate(MetadataImplementor metadata, SessionFactoryImplementor sessionFactory, 
         SessionFactoryServiceRegistry serviceRegistry) {
    
    }
    
    @Override
    public void disintegrate(SessionFactoryImplementor sessionFactory, 
         SessionFactoryServiceRegistry serviceRegistry) {
    
    }
}

MyIntegrator isimli org.hibernate.integrator.spi.Integrator interface'ini implement eden bir sınıf tanımladık. Bu sınıfın integrate() metodu içerisinde ise event listener'ları set ettik.

Örnekte yer alan MyPreLoadFirstListener, MyPreLoadSecondListener isimli sınıflar ise şunlardır:
import org.hibernate.event.spi.PreLoadEvent;
import org.hibernate.event.spi.PreLoadEventListener;
    
public class MyPreLoadFirstListener implements PreLoadEventListener {
    @Override
    public void onPreLoad(PreLoadEvent event) {
          //entity getEntity metodu ile cagrilir. Admin bir entity sinifidir
          if(event.getEntity() instanceof Admin){
                 System.out.println("1");
          }

    }
}
    
public class MyPreLoadSecondListener implements PreLoadEventListener {
    @Override
    public void onPreLoad(PreLoadEvent event) {
        System.out.println("2");
    }
}

Ekran çıktısı 1 1 2 şeklinde olacaktır.

Not: PreLoadEvent sınıfının ve diğer event sınıflarının(PostLoadEvent, PreInsertEvent vs.) getEntity() metodu kullanılarak hangi Entity'nin bu event'i meydana getirdiği bulunur. Genelde event listener implementasyonlarında instanceOf operatörü kullanılır.

Not: Eklenen servisleri kapatmak için aşağıdaki kodu eklemek gereklidir:
//burada getEventListenerGroup ayni turden olan listener'lari getirir. Tur belirtmek icin EventType enum kullanilir
eventListenerRegistry.getEventListenerGroup(EventType.PRE_LOAD).clear();


Son olarak META-INF klasörü yaratılır. Bu klasörün içine services isimli klasör eklenir. services klasörününe ise org.hibernate.integrator.spi.Integrator dosyası eklenir. Bu dosyanın içerisinde Integrator interface'ini implement eden sınıf ismi/isimleri yazılır. Örneğimizdeki MyIntegrator sınıfı paket adıyla birlikte aşağıdaki gibi yazılmıştır:
mucayufa.hibernate.eventListeners.MyIntegrator

© 2019 Tüm Hakları Saklıdır. Codesenior.COM