2017-02-17 4 views
1

Ich habe einen Ereignis-Listener für Überwachungsvorgänge über meine Entitäten implementiert. Zum Beispiel habe ich einen für PreInsertEventListener namens HibernatePreInsert erstellt. Beim Lesen von Stackoverflow habe ich einen Integrator namens HibernateIntegrator konfiguriert. Da ich Hibernate 4 und Spring 4 verwende, habe ich eine Datei unter META-INF/services mit dem Namen com.dacasals.raspertwo.interceptors.HibernateInterceptor erstellt und dort die Integrator-Klasse hinzugefügt, wie im Web und auch hier empfohlen. Aber wenn ich meine Anwendung starte und ein neues Element einfüge, passiert nichts, nicht einmal die Nachrichten meines HibernatePrePersist werden angezeigt. Dies ist das erste Mal, dass ich Hibernate EventListeners ausprobiere, und ich weiß nicht, woran es liegen könnte.Ereignis-Listener funktioniert nicht bei Hibernate?

Hier und als Beispiel der in meinem Problem beteiligten Klassen, auch die Strukturdatei:

Der Zuhörer:

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; 
    } 
} 

Der Integrator:

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 

    } 

} 

Die Datei com.dacasals .raspertwo.interceptors.HibernateInterceptor:

com.dacasals.raspertwo.interceptors.HibernateInterceptor 

Vielen Dank im Voraus.

BEARBEITET: Ich machte einen Fehler beim Schreiben. Ich benutze Hibernate 5, nicht 4.

+0

Was ist das Ziel Ihres Zuhörers? Möchten Sie Werte für das Objekt selbst festlegen oder möchten Sie eine Zeile in eine andere Tabelle einfügen? – Naros

+0

Ich möchte Informationen über das ausgeführte Ereignis in meiner Datenbank speichern. Wenn beispielsweise eine neue Person eingefügt wird, möchte ich den Zeitstempel der ausgeführten Operation speichern. Ich habe versucht, dieses einfache Beispiel mit der onPreInsert-Methode zu machen, aber es ist nichts passiert. Dann habe ich eine Nachricht angezeigt und festgestellt, dass nichts passiert ist. – Ethan

+0

Ich gehe davon aus, dass Sie nur die Hibernate-Core-Abhängigkeit mit Hibernate 4 importieren und nicht die 'hibernate-entitymanager'-Abhängigkeit verwenden und mit einer' SessionFactory' arbeiten. Ist das eine korrekte Annahme? – Naros

Antwort

4

Ich habe meine Zuhörer zur Arbeit ohne die Methode, die ich zuvor gefunden habe. Stattdessen eine Datei mit dem Dienst zu definieren, habe ich eine neue Klasse, wo ich meine umgesetzt Ereignis-Listener wie folgt registrieren:

@Component public class 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); 
} 

}

Und jetzt bin kann hören, wenn eine meiner Entitäten eingefügt, aktualisiert oder gelöscht wird. Ich hoffe, dass diese Lösung auch für andere Entwickler funktioniert.

2

Da alles, was Sie tun möchten, ist die Entität mit dem Ereignis verbunden zu manipulieren, würde ich die Verwendung von @PrePersist hier befürworten.

Sie können Hibernate dazu veranlassen, die JPA-Integratorrückrufe weiterhin auszuführen, selbst wenn die Anwendung keine JPA-Funktionen verwendet und weiterhin die native SessionFactory-Konfiguration verwendet. Für Hibernate vor Version 5.2 müssen Sie sicherstellen, dass Sie auch die entsprechende Version hibernate-entitymanager in Ihren Abhängigkeitsklassenpfad aufnehmen, die derselben Version der hibernate-core-Abhängigkeit entspricht. Für Hibernate 5.2 und darüber hinaus ist alles, was Sie benötigen, hibernate-core, die Sie offensichtlich bereits verwenden.

Als nächstes wird META-INF/services/org.hibernate.integrator.spi.Integrator eingerichtet.

Für Hibernate vor 4.2 müssen Sie hinzufügen:

org.hibernate.ejb.event.JpaIntegrator

Für Hibernate 4.3 und 5.x, die Sie hinzufügen müssen:

org.hibernate.jpa.event.spi.JpaIntegrator

Sie sollten jetzt den Rückruf @PrePersist verwenden können, auch wenn Ihre Konfiguration keine JPA EntityManager bootet.

Wenn Sie Ihre Anwendung speziell für die Verwendung von JPA portieren, können Sie diese Integratorkonfiguration möglicherweise entfernen, da die erstellte JPA EntityManager diese Rückrufe automatisch registriert und ausführt.

UPDATE

Sollten Sie sich entscheiden Sie ein Hibernate EventListener verwenden möchten, würde ich sicherstellen, dass beide integrate Methoden, die Zuhörer zu registrieren. Ich glaube, die von Ihnen implementierte Lösung wurde für Legacy-Verträge verwendet, aber ich glaube, dass die späteren Versionen von Hibernate die andere Signatur verwenden, die Sie noch nicht implementiert haben. Das könnte der Grund sein, warum dein Zuhörer nicht feuert.

+0

Ich werde nach der Implementierung der zweiten 'integrate' Methode suchen. Ich habe deine Antwort gelesen, und ich habe die Annotationsmethode ausprobiert, aber ich brauche sie diesmal nicht. Ich versuche das mit den EvenListeners zu machen. – Ethan

Verwandte Themen