6

I have a simple HibernateInterceptor in which basically I want to set a few fields automatically. This interceptor (shown below) extends 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;
    } 
}

I am wiring using a spring config file as follows:

<!-- 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>

However, the Interceptor is never reached. Does anyone have any clue? I have also tried adding the following to the transaction manager bean definition as follows:

<property name="entityInterceptor">
        <ref local="entityAuditInterceptor"/>
    </property>
Kros
  • 848
  • 1
  • 10
  • 24

2 Answers2

14

Ok, just for the record, I solved this problem which turned out to be a stupid mistake from my part.

When I implemented my interceptor that extends EmptyInterceptor I added the method 'onFlushDirty' and so on. So far so good. The problem was that on using my IDE to auto-import the used classes, I ended up importing java.reflect.Type instead of org.hibernate.type.Type by mistake. Hence, I was not really overriding the interceptor method!

I noticed that when I added the @Override interceptor to my method.

Another mystery solved ... :)

Kros
  • 848
  • 1
  • 10
  • 24
  • @Kros may you look at very similar question http://stackoverflow.com/questions/27602318/hibernate-myinterceptoronflushdirty-is-never-called pls? – VB_ Dec 22 '14 at 14:27
  • I've had the same problem - java.reflect.Type instead of org.hibernate.type. Fortunately I've found this answer! – olivmir Feb 27 '18 at 13:21
1

It looks like your Spring XML configuration is correct, so Hibernate should be calling your interceptor methods. However those methods appear to always return false which means that Hibernate will ignore any changes you make.

When you change a value you must return true. For example, this code iterates through all the properties and returns true if and only if a change is made:

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;
}
gutch
  • 6,959
  • 3
  • 36
  • 53
  • Hi gutch ... I have commented out parts of the code so that the question here is shorter. My problem is that it does not enter the interceptor at all. I have placed a breakpoint in the interceptor. Yet, it is never executed. I am really clueless. – Kros Apr 13 '12 at 09:57
  • @gutch could you look at very similar question http://stackoverflow.com/questions/27602318/hibernate-myinterceptoronflushdirty-is-never-called pls? – VB_ Dec 22 '14 at 14:27