2017-02-17 10 views
1

私は自分のエンティティに対する操作を監査するイベントリスナーを実装しました。たとえば、HibernatePreInsertというPreInsertEventListenerに1つ作成しました。また、私はHibernateIntegratorと呼ばれるインテグレータを設定しました。私は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 

ありがとうございます。

EDITED: 私は間違いを犯しました。私はHibernate 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-core依存関係の同じバージョンに一致する依存関係クラスパスに適切なバージョン番号hibernate-entitymanagerも含めるようにする必要があります。 Hibernate 5.2以降では、インクルードする必要があるのは、明らかに既に使用しているhibernate-coreです。

次に、META-INF/services/org.hibernate.integrator.spi.Integratorを設定します。

前にあなたが追加する必要が4.2に休止状態の場合

:Hibernateは4.3と5.xの

org.hibernate.ejb.event.JpaIntegrator

を、あなたが追加する必要があります。

org.hibernate.jpa.event.spi.JpaIntegrator

設定がJPA EntityManagerをブートストラップしない場合でも、@PrePersistコールバックを使用できるようになりました。

JPAを使用するようにアプリケーションを移植すると、JPA組み込みのEntityManagerがこれらのコールバックを自動的に登録して実行するため、最終的にこのインテグレータ構成を削除できます。

UPDATE

はあなたが私は両方integrate方法は、そのリスナーを登録してくださいだろう、あなたは休止状態EventListenerを使用したい決定する必要があります。私が実装したものは従来の契約のために残っていたと思いますが、Hibernateのそれ以降のバージョンではまだ実装されていない他のシグネチャを使用していると思います。それがあなたのリスナーが発砲しない理由です。

+0

私は2番目の 'integrate'メソッドの実装を探します。私はあなたの答えを読んで、私は注釈のアプローチを試みましたが、私は今この時間を必要としません。私はEvenListenersを使ってこれをしようとしています。 – Ethan

関連する問題