Hibernate event listener - postFlush equivalent

坚强是说给别人听的谎言 提交于 2021-01-29 03:09:59

问题


I am implementing a simple audit log functionality using hibernate event listeners. I wanted to accumulate all the changes for all entities in a transaction and handle auditing.

By using hibernate interceptors approach we have postFlush() where we handle auditing of all the accumulated audit events.

What is the equivalent for event listeners?

I tried using 'hibernate.ejb.event.flush' event. But it invokes very beginning of the life cycle, even before onPostInsert, onPostUpdate and onPostDelete events. So cannot accumulate changes.

Also tried with auto-flush, it also didn't work. Any idea?


回答1:


Just not to misled others, I figured it out that flush event listener actually works. The problem is default hibernate event listeners are not registered. When I register default event listeners along with custom listener, it started working fine.




回答2:


If you are implementing auditing with hibernate, I would recommend you to use Envers. Auditing with Envers is as simple as annotating the entity with @Audited annotation




回答3:


I audit this way, but dates are ugly..

persistence.xml

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

java code

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

}


来源:https://stackoverflow.com/questions/12706394/hibernate-event-listener-postflush-equivalent

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!