【问题标题】:Not able to insert an audit from Hibernate Interceptor无法从 Hibernate Interceptor 插入审计
【发布时间】:2017-08-17 02:31:48
【问题描述】:

我在尝试调试时遇到了问题。我的目标是尝试从休眠拦截器中保存审计。我正在使用 spring boot (1.5.3) 和 hibernate 5.0.12

这里是来自 sql 的休眠 sql 日志

休眠:选择 nextval ('user_sequence')

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

休眠:选择 nextval ('audit_sequence')

完成后刷新

如您所见,它获取了审计对象的 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");
}

【问题讨论】:

    标签: java spring hibernate jpa transactions


    【解决方案1】:

    我希望这对你有所帮助,这就是我为我的应用程序(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> 
    

    【讨论】:

    • 我正在使用弹簧靴。在 application.properties 中, spring.jpa.properties.hibernate.ejb.interceptor=AuditInterceptor 。我正在使用 spring jpa 和 sping 数据。我将尝试您使用 HibernateUtil 的方法。但我想让它与 spring 一起工作
    • @paul 我实际上是在春天做的,但不是春季靴子。
    • @paul 在这一行做一个断点 service.add(audits.get(id));看看里面有没有值?
    • 如果你使用下面的代码,你也会看到同样的问题 Service("audit") public class AuditServiceImpl implements AuditService { Autowired AuditRepository repo;事务(值 = “transactionManager”,传播 = Propagation.REQUIRED)公共审计添加(审计 obj){返回 repo.save(obj); }
    【解决方案2】:

    我自己解决了这个问题。我按照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;
    
    }
    

    }

    【讨论】:

      猜你喜欢
      • 2012-04-23
      • 2016-03-03
      • 1970-01-01
      • 2011-07-07
      • 2023-03-24
      • 2015-12-14
      • 1970-01-01
      • 2021-09-05
      • 1970-01-01
      相关资源
      最近更新 更多