使用拦截器在Hibernate中进行审计跟踪设计

时间:2016-09-29 11:41:30

标签: hibernate interceptor audit-logging

我是Hibernate的新手,希望在大多数表中维护审计信息(但不是全部)。这是完成的工作。

Employee.java

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

@Id
@GeneratedValue
@Column(name = "ID")
private long id;
@Column(name = "FIRSTNAME")
private String firstName;
@Column(name = "LASTNAME")
private String lastName;
@Column(name = "EMAIL")
private String email;
@Column(name = "PHONE")
private String phone;
@Embedded
AuditInformation auditInformation;

AuditInformation.java

@Embeddable
public class AuditInformation implements Auditable {

    @Column(name = "Created_Date")
    private Date createdDt;
    @Column(name = "Created_By")
    private String createdBy;
    @Column(name = "Last_modified_by")
    private String lastModifiedBy;
    @Column(name = "last_modified_Date")
    private Date lastModifiedDt;

Auditable.java

public interface Auditable {
    public void setCreatedDt(Date createdDt);    
    public Date getCreatedDt();    
    public void setLastModifiedDt(Date createdDt);
    public Date getLastModifiedDt();
}

AuditInfoInterceptor.java

public class AuditInfoInterceptor extends EmptyInterceptor {

    @Override
    public boolean onFlushDirty(final Object entity, final Serializable id,
            final Object[] currentState, final Object[] previousState,
            final String[] propertyNames, final Type[] types) {

        if (entity instanceof Auditable) {
            for (int i = 0; i < propertyNames.length; i++) {
                if (propertyNames[i] == "createdDt") {
                    currentState[i] = new java.util.Date();
                    return true;
                }
                if (propertyNames[i] == "lastModifiedDt") {
                    currentState[i] = new java.util.Date();
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean onSave(final Object entity, final Serializable id,
            final Object[] state, final String[] propertyNames,
            final Type[] types) {
        if (entity instanceof Auditable) {
            for (int i = 0; i < propertyNames.length; i++) {
                if (propertyNames[i] == "createdDt") {
                    state[i] = new java.util.Date();
                    return true;
                }
                if (propertyNames[i] == "lastModifiedDt") {
                    state[i] = new java.util.Date();
                    return true;
                }
            }
        }
        return false;    
    }
}

弹簧context.xml中

<bean id="hibernate4AnnotationSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>Employee</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>

        <property name="entityInterceptor" ref="auditInterceptor" />

现在我想将审核信息存储到数据库中,在使用save()方法填充对象后,我可以存储该数据库。但我的拦截器没有进行任何更新,因为它失败了instanceof检查并且什么也没做。现在我的问题是

  • 为什么lastModifiedDt属性/对象可用于我的拦截器,因为它只查找实体(在我的情况下是Employee)?

请提示是否设计正确。因为我正处于学习阶段。因此,试图以这种方式。在此之后我会寻找Hibernate Envers

提前致谢

1 个答案:

答案 0 :(得分:0)

lastModifiedDt之所以存在,是因为您将AuditInformation嵌入为Employee的属性。然后,它成为实体statepropertyNames的一部分。