5

我有一个简单的 HibernateInterceptor,基本上我想在其中自动设置一些字段。这个拦截器(如下所示)扩展了 EmptyInterceptor:

public class EntityAuditInterceptor extends EmptyInterceptor {

    /**
     * The Serial Version UUID.
     */
    private static final long serialVersionUID = 4636626262147801287L;

    /* (non-Javadoc)
     * @see org.hibernate.EmptyInterceptor#onFlushDirty(java.lang.Object, java.io.Serializable, java.lang.Object[], java.lang.Object[], java.lang.String[], org.hibernate.type.Type[])
     */
    public boolean onFlushDirty(Object entity,  Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {

        // doing stuff here

        return false;
    }

    /* (non-Javadoc)
     * @see org.hibernate.EmptyInterceptor#onSave(java.lang.Object, java.io.Serializable, java.lang.Object[], java.lang.String[], org.hibernate.type.Type[])
     */
    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {

                // doing stuff here
        return false;
    } 
}

我正在使用弹簧配置文件进行接线,如下所示:

<!-- Hibernate SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="hsqlDbDataSource"/>

        <property name="packagesToScan">
            <list>
                <value>com.dreamteam.lms.**.*</value>
            </list>
        </property>

        <!-- Adding Interceptor here -->
        <property name="entityInterceptor">
            <bean class="com.dreamteam.lms.interceptors.EntityAuditInterceptor"></bean>
        </property>


        <property name="hibernateProperties">
            <props>
                <!--<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>-->
                <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
                <prop key="hibernate.generate_statistics">true</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.cache.use_second_level_cache">true</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
                <prop key="hibernate.cache.use_query_cache">true</prop>
                <prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop>
            </props>
        </property>
    </bean>

但是,永远无法到达拦截器。有没有人有任何线索?我还尝试将以下内容添加到事务管理器 bean 定义中,如下所示:

<property name="entityInterceptor">
        <ref local="entityAuditInterceptor"/>
    </property>
4

2 回答 2

14

好的,为了记录,我解决了这个问题,结果证明这是我的一个愚蠢的错误。

当我实现扩展 EmptyInterceptor 的拦截器时,我添加了方法“onFlushDirty”等等。到目前为止,一切都很好。问题是在使用我的 IDE 自动导入使用的类时,我最终错误地导入了 java.reflect.Type 而不是 org.hibernate.type.Type。因此,我并没有真正覆盖拦截器方法!

我注意到当我将 @Override 拦截器添加到我的方法时。

另一个谜团解开了...... :)

于 2012-04-14T15:44:24.637 回答
1

看起来你的 Spring XML 配置是正确的,所以 Hibernate 应该调用你的拦截器方法。然而,这些方法似乎总是返回false,这意味着 Hibernate 将忽略您所做的任何更改。

当你改变一个值时,你必须返回true。例如,此代码遍历所有属性并true在且仅当进行更改时才返回:

public boolean onFlushDirty(Object entity,  Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
    boolean changed = false;
    for (int i = 0; i < propertyNames.length; i++) {
        if ("saveDate".equals(propertyNames[i])) {
            currentState[i] = new Date();
            changed = true;
        }
    }
    return changed;
}
于 2012-04-13T00:03:30.007 回答