2016-11-24 7 views
0

Я хочу, чтобы в моей базе данных выполнялись операции над таблицей (вставляет, обновляет и удаляет). Я читал о перехватчиках, поэтому я реализовал свои собственные.Errror с методом postFlush в Hibernate Interceptors

Например, когда выполняется вставка я это сделать:

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

Наконец, в postFlush я это сделать:

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

В реестре, где я хранить информацию об операциях, выполняемых на столе, который я проверяю.

У меня было много проблем при вызове перехватчика в классе с помощью методов сохранения, обновления и удаления. После нескольких часов чтения в Интернете и здесь (я люблю этот сайт Jeje) Я был в состоянии назвать Перехватчик так:

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

Я бегу мой простой веб-приложение, чтобы сохранить имя и страну человека. Мне удалось сохранить информацию о человеке, но моя таблица реестра была пуста. Я отлаживал свой код, и метод 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 = новый реестр (операция, дата) ; ' Несмотря на незначительные изменения, метод postFlush никогда не выполняется во время запуска моего приложения. – Ethan

+0

Здесь отлично работает, попробуйте отладить эти коды и изменить их. Например, вы можете использовать запрос вместо сравнения полей. – erickdeoliveiraleal

+0

Привет, эрик, он работает !!! Я отлаживал код и обнаружил ошибку в классе mi DAO, теперь я могу проверить свои данные. Я просто не знаю, почему вы сказали, что даты были уродливыми, в моей таблице базы данных они выглядят так: «2017-02-07 16: 29: 39.07». В любом случае, большое вам спасибо за вашу помощь. – Ethan