2016-09-23 4 views
2

Ich möchte einige Prüfungen vor dem Speichern einer Sammlung von Kindern eines Objekts (Kaskade = alle) ausführen.Hibernate Interceptor oder Listener mit Spring Boot und Spring-Daten JPA

Ich benutze Spring Boot und Spring Data JPA und fragte mich, welcher Ansatz der beste wäre: ein Hibernate Listener oder ein Interceptor. Was sind die Vor-/Nachteile von jedem? Hast du zufällig ein Beispiel für den, den du für den besten Ansatz hältst?

Ich habe Hibernate Hörer verwendet, bevor sie in XML wie folgt konfiguriert:

<property name="eventListeners"> 
     <map> 
      <entry key="post-update"> 
       <list> 
        <ref bean="myListener" /> 
       </list> 
      </entry> 
     </map> 
    </property> 

auf der Sitzung Fabrik (älteres Projekt). Aber jetzt sind die meisten meiner Konfigurationen in Annotationen (Ursache Spring Boot) und ich möchte die Konfigurationen so einfach und leicht wie möglich halten, also wäre vielleicht ein Interceptor eine bessere Lösung.

Vielen Dank.

Antwort

5

Ich habe mich viel umgesehen und gedacht, ich würde teilen, woran ich gearbeitet habe (ich habe die hilfreichen (nicht inline) Links unten eingefügt).

Interceptor

einen Abfangjäger verwenden, können Sie die org.hibernate.EmptyInterceptor Klasse erweitern und die Methoden außer Kraft setzen Sie abfangen wollen. Wahrscheinlich möchten Sie onSave(...) in Ihrem Fall.

package foo.bar; 

import org.hibernate.EmptyInterceptor; 
import org.hibernate.type.Type; 
import java.io.Serializable; 

public class MyInterceptor extends EmptyInterceptor { 
    @Override 
    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { 
     // do your checks here 
     return false; 
    } 
} 

Sie müssen register your interceptor mit Spring/Hibernate. Sie können dies in Ihrem application.properties or application.yml tun.

spring: 
    jpa: 
    properties: 
     hibernate.ejb.interceptor: foo.bar.MyInterceptor 

Die upsides zu Abfangjäger sind, dass es (möglicherweise) weniger Code und relativ einfache Konfiguration. Die Nachteile sind, dass Sie nur eine für Ihre gesamte Anwendung haben und die API kann verwirrend sein, mit zu arbeiten.

Ereignis-Listener

Für Veranstaltungen, implementieren Sie eine org.hibernate.event.spi.*Listener Schnittstellen des Hibernate. Sie möchten wahrscheinlich die org.hibernate.event.spi.PreInsertEventListener in Ihrem Fall.

Sie müssen Ihre Veranstaltung in der EventListenerRegistry registrieren. Um dies zu tun, können Sie Ihre Klasse @Component, @Autowire der EntityManagerFactory in Ihre Klasse machen und erstellen Sie eine Methode, um Ihre Klasse zu registrieren.

package foo.bar; 

import org.hibernate.event.service.spi.EventListenerRegistry; 
import org.hibernate.event.spi.EventType; 
import org.hibernate.event.spi.PreInsertEvent; 
import org.hibernate.event.spi.PreInsertEventListener; 
import org.hibernate.internal.SessionFactoryImpl; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Component; 
import javax.annotation.PostConstruct; 
import javax.persistence.EntityManagerFactory; 

@Component 
public class MyEventListener implements PreInsertEventListener { 
    @Autowired 
    private EntityManagerFactory entityManagerFactory; 

    @PostConstruct 
    private void init() { 
     SessionFactoryImpl sessionFactory = entityManagerFactory.unwrap(SessionFactoryImpl.class); 
     EventListenerRegistry registry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class); 
     registry.getEventListenerGroup(EventType.PRE_INSERT).appendListener(this); 
    } 

    @Override 
    public boolean onPreInsert(PreInsertEvent preInsertEvent) { 
     // do your checks here 
     return false; 
    } 
} 

Die upsides Hörern sind, dass Sie so viele haben, wie Sie wollen, das API schöner als die Abfangjäger ist, und der Code und die Konfiguration sind alle an einem Ort. Der Nachteil ist, dass die Konfiguration ist länger und komplizierter.


+0

Hibernate unterstützt Sitzung Abfangjäger auch ass Anwendung scoped scoped Sie diese Eigenschaft verwenden müssen, statt "hibernate.ejb.interceptor.session_scoped" – cyberoblivion

+0

Das ist großartig, ich habe viel nach dir gesucht und dir gute Anweisungen gegeben. –

Verwandte Themen