2016-11-24 6 views
0

テーブルに対して実行された操作(挿入、更新、削除)をデータベースにログインしたいとします。私はインターセプタについて読んできたので、自分で実装しました。私はこれを行うpostFlushにおける最後HibernateインターセプタのメソッドpostFlushでエラーが発生しました

@Override 
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { 
    if (entity instanceof Person) { 
     System.out.println("Se ha insertado una persona"); 
     operation = "Insert"; 
     date = Calendar.getInstance().getTime(); 
     return true; 
    } 
    return false; 
} 

:挿入が私はこれを行うに行われる。例えば

、Iは、実行される動作についての情報を格納する場合、レジストリに

// called after committed into database 
public void postFlush() { 
    System.out.println("postFlush"); 
    Session ses = HibernateUtil.getSessionFactory().openSession(); 
    ses.getTransaction().begin(); 
    Registry reg = new Registry(operation, date); 
    ses.save(reg); 
    ses.getTransaction().commit(); 
} 

でありますテーブルで私はチェックしています。

クラスのインターセプタを呼び出して保存、更新、削除するメソッドで多くの問題が発生しました。私は名前と人の国を救うために私の簡単なWebアプリケーションを実行

Session session = this.sessionFactory.withOptions().interceptor(new MyInterceptor).openSession(); 

:時間は、インターネット上で読んで、ここで(私はこのサイトjejeを愛する)後、私はこの方法インターセプタを呼び出すことができました。私はその人の情報を保存することができましたが、私のレジストリテーブルは空でした。コードをデバッグし、メソッドpostFlushが呼び出されたことはありませんでした。何か案は?私は様々なチュートリアルやいくつかの推奨事項に従ってきましたが、何も動作していないようです。

私が最後に試みたのは、非常に「汚い」方法でした。この(恐ろしい)の方法に

@Override 
@Transactional 
public void addPerson(Person p) { 
    Session session = this.sessionFactory.withOptions().interceptor(new MyInterceptor).openSession(); 
    session.save(p); 
    logger.info("Person saved successfully, Person Details="+p); 
} 

:私はこのことから私のコードを変更し

@Override 
@Transactional 
public void addPerson(Person p) { 
    MyInterceptor m = new MyInterceptor(); 
    Session session = this.sessionFactory.withOptions().interceptor(m).openSession(); 
    Transaction tx = session.beginTransaction(); 
    session.save(p); 
    tx.commit(); 
    session.flush(); 
    m.postFlush(); 
    logger.info("Person saved successfully, Person Details="+p); 
} 

そして、それは働きました!私は人の情報やレジストリにも情報を格納することができましたが、これは正しい方法ではありませんか?事前

答えて

0

おかげで、私はこの方法を監査するが、日付は醜い..です

persistence.xmlの

<property name="hibernate.ejb.interceptor" value="siapen.jpa.interceptor.MeuInterceptador" /> 

Javaコード

import java.io.Serializable; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.Iterator; 

import org.apache.commons.lang3.ObjectUtils; 
import org.hibernate.CallbackException; 
import org.hibernate.EmptyInterceptor; 
import org.hibernate.type.Type; 

import siapen.model.BaseEntity; 

public class MeuInterceptador extends EmptyInterceptor { 

    private static final long serialVersionUID = 7853236444153436270L; 

    private String strSQL = ""; 
    String acao; 
    @SuppressWarnings("rawtypes") 
    BaseEntity entity; 
    String s = ""; 

    @SuppressWarnings("unchecked") 
    // 1 
    public boolean onSave(Object obj, Serializable id, Object[] valores, String[] propertyNames, Type[] types) 
      throws CallbackException { 
     if (obj instanceof BaseEntity) { 
      entity = (BaseEntity) obj; 
      for (int i = 0; i < valores.length; i++) { 
       if (valores[i] != null && !valores[i].equals("")) { 
        s += propertyNames[i] + ":" + valores[i]; 
        if (i != valores.length - 1) { 
         s += "___"; 
        } 
       } 
      } 
     } 
     return false; 
    } 

    @SuppressWarnings("unchecked") 
    // 1 
    public boolean onFlushDirty(Object obj, Serializable id, Object[] valoresAtuais, Object[] valoresAnteriores, 
      String[] propertyNames, Type[] types) throws CallbackException { 
     if (obj instanceof BaseEntity) { 
      entity = (BaseEntity) obj; 

      for (int i = 0; i < valoresAtuais.length; i++) { 

       if (!ObjectUtils.equals(valoresAtuais[i], valoresAnteriores[i])) { 
        if (!s.equals("")) { 
         s += "___"; 
        } 
        s += propertyNames[i] + "-Anterior:" + valoresAnteriores[i] + ">>>Novo:" + valoresAtuais[i]; 
       } 
      } 
     } 
     return false; 

    } 

    @SuppressWarnings("unchecked") 
    // 1 
    public void onDelete(Object obj, Serializable id, Object[] state, String[] propertyNames, Type[] types) { 
     if (obj instanceof BaseEntity) { 
      entity = (BaseEntity) obj; 
     } 
    } 

    // CHAMADO ANTES DO COMMIT 
    // 2 
    @SuppressWarnings("rawtypes") 
    public void preFlush(Iterator iterator) { 
    } 

    // 3 
    public String onPrepareStatement(String sql) { 
     acao = ""; 
     if (sql.startsWith("/* update")) { 
      acao = "update"; 
     } else if (sql.startsWith("/* insert")) { 
      acao = "insert"; 
     } else if (sql.startsWith("/* delete")) { 
      acao = "delete"; 
     } 
     if (acao != null) { 
      strSQL = sql; 
     } 
     return sql; 
    } 

    // CHAMADO APÓS O COMMIT 
    // 4 
    @SuppressWarnings("rawtypes") 
    public void postFlush(Iterator iterator) { 
     if (acao != null) { 
      try { 
       if (acao.equals("insert")) { 
        AuditLogUtil audi = new AuditLogUtil(); 
        audi.LogIt("Salvo", entity, s); 
       } 
       if (acao.equals("update")) { 
        AuditLogUtil audi = new AuditLogUtil(); 
        audi.LogIt("Atualizado", entity, s); 
       } 
       if (acao.equals("delete")) { 
        AuditLogUtil audi = new AuditLogUtil(); 
        audi.LogIt("Deletado", entity, ""); 
       } 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } finally { 
       strSQL = ""; 
       s = ""; 
      } 
     } 
    } 

} 
+0

こんにちは@erickdeoliveiraleal、私が試しましたあなたのソリューションとpostFlushメソッドまで正常に動作します。エンティティではなく、実行された操作と日付を保存するためにコードを変更しました。あなたは 'audi.LogIt(" Atualizado "、entity、s)'を持っていて、 'reg = new Registry(operation、date) ; ' この小さな変更にもかかわらず、メソッドpostFlushはアプリケーションの実行中に決して実行されません。 – Ethan

+0

完全に動作します。このコードをデバッグして修正してみてください。たとえば、フィールドを比較する代わりにクエリを使用できます。 – erickdeoliveiraleal

+0

こんにちは、それは動作します!コードをデバッグし、mi DAOクラスのエラーを見つけました。私のデータを監査できるようになりました。私はちょうどあなたが日付が醜いと言った理由を知らない、彼らは "2017-02-07 16:29:39.07"のように見える私のデータベーステーブルでは。とにかく、ありがとうございました。 – Ethan

関連する問題