一尘不染

如何在不使用Hibernate拦截器创建审计跟踪表的情况下从数据库获取而不获取previouseState?

hibernate

我正在尝试创建一个审计表,它将最终看起来像这样:

实体,id,属性,旧值,新值,用户,时间戳

使用hibernate的EmptyInterceptor,
我希望这个表会有很多IO。似乎onFlushDirty方法中的previouseState无法正常工作。

我怎么能不得到如图所示从数据库中获取它的旧值在这里?

public class AuditLogInterceptor extends EmptyInterceptor {
    private Set inserts    = new HashSet();
    private Set updates    = new HashSet();
    private Set deletes    = new HashSet();
    private Map oldies     = new HashMap();

    @Override
    public boolean onSave(Object entity,
                          Serializable id,
                          Object[] state,
                          String[] propertyNames,
                          Type[] types)
            throws CallbackException {
        if (entity instanceof Auditable)
            inserts.add((Auditable)entity);
        return false;
    }

    @Override
    public void onDelete(Object entity, Serializable id, Object[] state,
            String[] propertyNames, Type[] types) {
        if (entity instanceof Auditable)
            deletes.add((Auditable)entity);
    }

    @Override
    public boolean onFlushDirty(Object entity,
                                Serializable id,
                                Object[] currentState,
                                Object[] previousState,
                                String[] propertyNames,
                                Type[] types)
            throws CallbackException {
        if (entity instanceof Auditable) {
            try {
                // Use the id and class to get the pre-update state from the database
                Session tempSession =
                    HibernateUtil.getSessionFactory().openSession();
                Auditable old = (Auditable) tempSession.get(entity.getClass(), ((Auditable) entity).getId());
                oldies.put(old.getId(), old);
                updates.add((Auditable)entity);
            } catch (Throwable e) {
                _log.error(e,e);
            }
        }
        return false;
    }

有没有一种方法可以获取获取更新前的状态而无需往返数据库?


阅读 254

收藏
2020-06-20

共1个答案

一尘不染

另一种方法是在加载时存储先前的状态。

@Entity
@Table(name='Foo')
class Foo {

    @Transient
    private Foo previousState;

    @PostLoad
    private void setPreviousState(){
        previousState = new Foo();
        //copy the fields
    }

    public Foo getPreviousState(){
        return previousState;
    }

}
2020-06-20