2016-11-24 1 views
0

Je veux connecter dans ma base de données les opérations exécutées sur une table (insertions, mises à jour et suppressions). J'ai lu sur Interceptors, alors j'ai mis en place le mien.Erreur avec la méthode postFlush dans les intercepteurs Hibernate

Par exemple, lorsqu'une je insertion est réalisé ceci:

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

Enfin, dans le postFlush que je fais ceci:

// 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(); 
} 

Enregistrez- est l'endroit où je stocke les informations sur les opérations exécutées sur la table je vérifie.

J'ai eu beaucoup de problèmes lors de l'appel de l'intercepteur sur la classe avec les méthodes pour enregistrer, mettre à jour et supprimer. Après des heures de lecture sur Internet et ici (j'adore ce site jeje) J'ai pu appeler l'intercepteur de cette façon:

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

je lance mon application simple Web pour enregistrer le nom et le pays d'une personne. J'étais capable de stocker les informations de la personne, mais ma table de registre était vide. J'ai débuggé mon code et la méthode postFlush n'a jamais été appelée. Des idées? J'ai suivi divers tutoriels et quelques recommandations, mais rien ne semble fonctionner.

La dernière chose que j'ai essayé était d'une manière très "sale". J'ai changé mon code de ceci:

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

à cette façon (horrible):

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

Et ça a marché! J'ai été capable de stocker des informations de personnes et aussi dans le registre, mais ce n'est pas la bonne façon hein?

Merci à l'avance

Répondre

0

je vérifie cette façon, mais les dates sont moches ..

persistence.xml

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

code 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

Bonjour @erickdeoliveiraleal, j'ai essayé votre solution et cela a bien fonctionné jusqu'à la méthode postFlush. J'ai changé le code afin de sauvegarder l'opération exécutée et la date, pas l'entité. Vous avez 'audi.LogIt (" Atualizado ", entité, s)' et je le remplace par 'reg = new Registre (opération, date) ; ' Malgré cette modification mineure, la méthode postFlush n'est jamais exécutée lors de l'exécution de mon application. – Ethan

+0

Ici fonctionne parfaitement, essayez de déboguer ces codes et de le modifier. Vous pouvez par exemple utiliser la requête au lieu de comparer les champs. – erickdeoliveiraleal

+0

Salut erick, ça marche !!! J'ai débugué le code et ai trouvé une erreur sur la classe mi DAO, maintenant Im capable d'auditer mes données. Je ne sais pas pourquoi vous avez dit que les dates étaient moche, sur ma table de base de données ils ressemblent à ceci "2017-02-07 16: 29: 39.07". En tout cas, merci beaucoup pour votre aide. – Ethan