无法从Hibernate Interceptor插入审核

时间:2017-08-17 02:31:48

标签: java spring hibernate jpa transactions

我一直在尝试调试此问题。我的目标是尝试从hibernate拦截器中保存审计。我正在使用spring boot(1.5.3)和hibernate 5.0.12

以下是来自sql

的hi​​bernate sql日志

休眠:选择nextval(' user_sequence')

Hibernate:插入用户(creation_time,deleted,description,modifiedby,modified_time,name,email,enabled,password,phone_num,role_id,gid)值(?,?,?,?,?,?,?,? ,?,?,?,?)

休眠:选择nextval(' audit_sequence')

POST FLUSH DONE

如您所见,它获取审计对象的nextval,但未插入值。

public void postFlush(@SuppressWarnings("rawtypes") Iterator iterator) throws CallbackException {  
    try { 
        AuditRepository auditRepo =(AuditRepository)ApplicationContextProvider.getApplicationContext().getBean("auditRepository");
        synchronized(audits) {
            for (Long id:audits.keySet()) {
                 auditRepo.save(audits.get(id));
            }
        }



    } catch (Exception e) {
        logger.error(e.toString(),e.toString());
    } finally {
        synchronized (audits) {
            audits.clear();
        }
    } 
    System.out.println("POST FLUSH DONE");
}

2 个答案:

答案 0 :(得分:0)

我希望这能帮到你,这就是我为我的应用程序做的(Hibernate 5.2.6):

import java.io.Serializable;
import java.util.Date;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.EmptyInterceptor;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.type.Type;

import com.demo.domain.AuditLog;
import com.demo.util.GlobUtil;

public class CustomInterceptor extends EmptyInterceptor
{
    private static final Logger log = LogManager.getLogger(CustomInterceptor.class);

    public static final String OPERATION_TYPE_INSERT = "INSERT";

    public static final String OPERATION_TYPE_UPDATE = "UPDATE";

    public static final String OPERATION_TYPE_DELETE = "DELETE";

    public static final String OPERATION_TYPE_SELECT = "SELECT";

    // delete
    public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
    {
        auditTrail(entity, id, null, state, propertyNames, types, OPERATION_TYPE_DELETE);
    }

    // update
    public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState,
            String[] propertyNames, Type[] types)
    {
        return auditTrail(entity, id, currentState, previousState, propertyNames, types, OPERATION_TYPE_UPDATE);
    }

    // select
    public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
    {
        // return auditTrail(entity, id, null, state, propertyNames, types, OPERATION_TYPE_SELECT);
        return true;
    }

    // insert
    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
    {
        return auditTrail(entity, id, state, null, propertyNames, types, OPERATION_TYPE_INSERT);
    }

    private boolean auditable(Object entity)
    {
        return (entity instanceof Auditable);
    }

    private boolean auditTrail(Object entity, Serializable id, Object[] currentState, Object[] previousState,
            String[] propertyNames, Type[] types, String operationType)
    {
        String prev = "";
        String curr = "";

        Session session = HibernateUtil.getSessionFactory().openSession();

        if (!auditable(entity))
        {
            return false;
        }

        try
        {
            for (int index = 0; index < propertyNames.length; index++)
            {
                if (previousState != null)
                {
                    prev = (previousState[index] == null) ? "" : previousState[index].toString();
                }

                if (currentState != null)
                {
                    curr = (currentState[index] == null) ? "" : currentState[index].toString();
                }

                AuditLog auditLog = new AuditLog(id.toString(), entity.getClass().toString(),
                        propertyNames[index], prev, curr, operationType, GlobUtil.getUserName(), new Date());

                session.beginTransaction();
                session.save(auditLog);
                session.getTransaction().commit();
            }
        }
        catch (HibernateException e)
        {
            session.getTransaction().rollback();
            log.error("Unable to process audit log for " + operationType + " operation", e);
        }
        finally
        {
            session.close();
        }

        return true;
    }
}

当然,在xml或java中声明CustomInterceptor

<property name="entityInterceptor">
    <bean class="com.demo.common.CustomInterceptor"/>
</property> 

答案 1 :(得分:0)

我解决了这个问题。我按照EntityManager.persist() doesn't insert data when using @Transactional

中的建议更改了代码
@Override  
public void postFlush(@SuppressWarnings("rawtypes") Iterator iterator) throws CallbackException {  
    try { 
        AuditService service = (AuditService)ApplicationContextProvider.getApplicationContext().getBean("audit");

        synchronized(audits) {
            for (Long id:audits.keySet()) {
                service.add(audits.get(id));
            }
        }
    } catch (Exception e) {
        logger.error(e.toString(),e.toString());
    } finally {
        synchronized (audits) {
            audits.clear();
        }
    } 
}


@Service("audit")
public class AuditServiceImpl  implements AuditService {

@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager em;


public Audit add(Audit obj) {
    em.persist(obj);

    return obj;

}

}