【问题标题】:Errror with method postFlush in Hibernate Interceptors在 Hibernate 拦截器中使用方法 post Flush 出错
【发布时间】:2016-11-24 13:32:52
【问题描述】:

我想在我的数据库中登录对表执行的操作(插入、更新和删除)。我一直在阅读有关拦截器的信息,所以我实现了自己的。

例如,当执行插入时,我会这样做:

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

它奏效了!我能够在注册表中存储人员信息,但这不是正确的方式吗?

提前致谢

【问题讨论】:

    标签: java spring hibernate interceptor


    【解决方案1】:

    我是这样审核的,但是日期很难看..

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

    【讨论】:

    • 您好@erickdeoliveiraleal,我尝试了您的解决方案,并且在使用 postFlush 方法之前效果很好。我更改了代码以保存执行的操作和日期,而不是实体。您有audi.LogIt("Atualizado", entity, s),我将其替换为reg = new Registry(operation, date); 尽管进行了微小的更改,但在运行我的应用程序时仍然不会执行 postFlush 方法。
    • 这里完美运行,尝试调试此代码并修改它。例如,您可以使用查询而不是比较字段。
    • 嗨,埃里克,它有效!!!我调试了代码并在 mi DAO 类上发现了一个错误,现在我可以审计我的数据了。我只是不知道你为什么说日期很难看,在我的数据库表上它们看起来像这样“2017-02-07 16:29:39.07”。无论如何,非常感谢您的帮助。
    • 这里可能有问题,我需要检查我的代码,当修改新的时间戳时,旧的会像 2015-07-29 00:00:00.0 一样打印,新的像 Sun Jan 29 00 :00:00 BRST 2017
    猜你喜欢
    • 1970-01-01
    • 2012-08-18
    • 1970-01-01
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2016-01-11
    • 1970-01-01
    相关资源
    最近更新 更多