2016-09-23 17 views
2

オブジェクトの子コレクションを保存する前にいくつかのチェックを実行したい(cascade = all)。SpringブートとSpringデータを持つHibernateインターセプタまたはリスナーJPA

私はSpringブートとSpring Data JPAを使用しており、どのようなアプローチが最高になるのだろうと思いました:Hibernateリスナまたはインターセプタ。それぞれの長所と短所は何ですか?最良のアプローチと考えている例の例がありますか?セッションファクトリ(古いプロジェクト)の

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

は私が前に、このようなXMLで構成されたHibernateのリスナーを使用していました。しかし、今では私のconfigsのほとんどがアノテーション(Spring Bootの原因)にあり、configsをできるだけシンプルで軽くしたいので、おそらくインターセプターがより良い解決策になるでしょう。

ありがとうございます。

答えて

5

私は自分自身のために多くのことを見て、私が働いていることを分かち合うと思っていました(私は役に立つ(非インライン)リンクを下に入れました)。

インターセプタ

インターセプターを使用するには、org.hibernate.EmptyInterceptorクラスを拡張し、あなたがインターセプトするメソッドをオーバーライドします。 あなたの場合はおそらくonSave(...)が必要です。

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

あなたは春/休止状態でregister your interceptorする必要があります。 application.properties or application.ymlでこれを行うことができます。

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

インターセプタの問題点は、(潜在的に)コードが少なく、比較的単純な構成であることです。 欠点は、アプリケーション全体に対して1つしか持たないことで、APIが扱いにくいということです。イベントでは

イベントリスナ

、あなたはHibernateのorg.hibernate.event.spi.*Listenerインタフェースのいずれかを実装します。 あなたのケースにはorg.hibernate.event.spi.PreInsertEventListenerが必要です。

EventListenerRegistryにイベントを登録する必要があります。 これを行うには、クラスに@Component,@AutowireEntityManagerFactoryを作成し、クラスを登録する@PostConstructメソッドを作成します。リスナーに

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

五分五分では、APIは、インターセプタのより進歩して、あなたが好きなだけを持つことができることであり、コードと構成は、一箇所ですべてです。 欠点は、コンフィギュレーションがより長くて複雑であることです。です。


+0

Hibernateがセッションをサポートしていますが、同様インターセプタをスコープ尻アプリケーションは、あなたの代わりにこのプロパティを使用する必要があるスコープ – cyberoblivion

+0

を "hibernate.ejb.interceptor.session_scoped"すごく面白かった、私はあなたのように良い指示を得ることがたくさん見えた。 –

関連する問題