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.
Integrator Interface
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:
Örnekte yer alan MyPreLoadFirstListener, MyPreLoadSecondListener isimli sınıflar ise şunlardı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:
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:
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