2017-02-17 78 views
1

我已經實現了一個事件偵聽器,用於對我的實體進行審計操作。例如,我爲PreInsertEventListener創建了一個名爲HibernatePreInsert的實例。另外,通過閱讀stackoverflow,我配置了一個名爲HibernateIntegrator的Integrator。由於我使用Hibernate 4和Spring 4,因此我在META-INF/services下創建了一個名爲com.dacasals.raspertwo.interceptors.HibernateInterceptor的文件,並在那裏添加了集成器類,正如網絡上推薦的那樣。但是當我運行我的應用程序並插入一個新元素時,什麼也沒有發生,甚至沒有顯示我的HibernatePrePersist的消息。這是我第一次嘗試Hibernate EventListeners,我不知道可能會出錯。事件監聽器不在Hibernate上工作?

這裏是和例子涉及我的問題類,也文件結構:

監聽器:

public class HibernatePreInsert implements PreInsertEventListener{ 
    private static final long serialVersionUID = 1L; 
    static final Logger logger = LoggerFactory.getLogger(HibernatePreInsert.class); 

    @Override 
    public boolean onPreInsert(PreInsertEvent event) { 
     if(event.getEntity() instanceof Person){ 
      //display a message to know if this works or not 
      logger.info("It works"); 
     } 
     return false; 
    } 
} 

積分:

public class HibernateIntegrator implements Integrator{ 

    public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry){ 
     final EventListenerRegistry registry = serviceRegistry.getService(EventListenerRegistry.class); 

     HibernatePreInsert listener = new HibernatePreInsert(); 

     registry.prependListeners(EventType.PRE_INSERT, listener); 
    } 

    @Override 
    public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory, 
      SessionFactoryServiceRegistry serviceRegistry) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) { 
     // TODO Auto-generated method stub 

    } 

} 

文件com.dacasals .raspertwo.interceptors.HibernateInterceptor:

com.dacasals.raspertwo.interceptors.HibernateInterceptor 

在此先感謝。

編輯: 我在寫作時犯了一個錯誤。我正在使用休眠5,而不是4.

+0

你的聽衆的目標是什麼?你想要在實體本身上設置值還是想要在另一個表中插入一行? – Naros

+0

我想在我的數據庫中存儲有關執行事件的信息。例如,如果插入新的Person,我想保存執行的操作的時間戳。我試圖在onPreInsert方法上做這個簡單的例子,但沒有發生任何事情,然後我顯示一條消息,並意識到什麼都沒有發生。 – Ethan

+0

我假設你只是用Hibernate 4導入'hibernate-core'依賴項,而不是使用'hibernate-entitymanager'依賴項並使用'SessionFactory'。這是一個正確的假設嗎? – Naros

回答

4

我讓聽衆在不使用我之前找到的方法的情況下工作。而不是定義與服務的文件,我創建了一個新的類,其中註冊我實現事件監聽器是這樣的:

@Component 公共類EscuchadorGeneral {

@PersistenceUnit 
private EntityManagerFactory emf; 

@Inject 
private InsertEvent insert; 

@Inject 
private UpdateEvent update; 

@Inject 
private DeleteEvent delete; 

@PostConstruct 
protected void init(){ 
    SessionFactoryImpl sF = emf.unwrap(SessionFactoryImpl.class); 
    EventListenerRegistry registry = sF.getServiceRegistry().getService(EventListenerRegistry.class); 
    registry.getEventListenerGroup(EventType.POST_INSERT).appendListener(insert); 
    registry.getEventListenerGroup(EventType.POST_UPDATE).appendListener(update); 
    registry.getEventListenerGroup(EventType.PRE_DELETE).appendListener(delete); 
} 

}

現在我可以在我的任何實體被插入,更新或刪除時收聽。我希望這個解決方案也適用於其他開發者。

2

由於您只想操作與事件關聯的實體,因此我會在此提倡使用@PrePersist

即使應用程序不使用任何JPA功能並繼續使用本地SessionFactory配置,您也可以愚弄Hibernate仍然激發JPA集成器回調。

對於5.2之前的Hibernate,您需要確保您的依賴類路徑中包含適當的版本爲hibernate-entitymanager,該版本符合hibernate-core依賴關係的相同版本。對於Hibernate 5.2及更高版本,您需要包含的內容是hibernate-core,您顯然已經使用它。下一步是設置META-INF/services/org.hibernate.integrator.spi.Integrator

對於之前的4.2 Hibernate,您需要添加:

org.hibernate.ejb.event.JpaIntegrator

對於休眠4.3和5.x,您需要添加:

org.hibernate.jpa.event.spi.JpaIntegrator

即使您的配置不引導JPA EntityManager,您現在也應該能夠使用@PrePersist回調。

然後,當您將應用程序移植到專門使用JPA時,最終可以刪除此集成器配置,因爲JPA內置的EntityManager將自動註冊並執行這些回調。

UPDATE

,你應該決定要使用Hibernate EventListener,我會確保這兩種方法integrate註冊該偵聽器。我認爲你實現的那個是留給遺留合同的,但我相信Hibernate的更高版本會使用你尚未實現的其他簽名。這可能是你的聽衆不開火的原因。

+0

我將搜索第二個'integrate'方法的實現。我讀了你的答案,並且我嘗試了註釋方法,但這次我不需要它。我試圖用EvenListeners來做到這一點。 – Ethan