Hibernate entity interceptor triggerd но установить значения не сохранение


Я работаю с весенним настроенным приложением hibernate. Существует transactionmanagement и auditInterceptor, определяемый как entityInterceptor. Когда я отлаживаю код, я ввожу методы entityInterceptors и устанавливаю дату, однако в конце сохранения они не находятся в базе данных :(.

Рассмотрим следующую конфигурацию

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">     
        <property name="dataSource" ref="dataSource" />
        <property name="hibernateProperties">
            <value>
                hibernate.dialect=${hibernate.dialect}
                hibernate.show_sql=${hibernate.show_sql}
                hbm2ddl.auto=${hbm2ddl.auto}
            </value>
        </property>
        <property name="schemaUpdate">
            <value>true</value>
        </property>
        <property name="annotatedClasses">
            <list>
                                .. bunch of annotatedClasses" ...
            </list>
        </property>
    </bean>

<bean name="auditInterceptor" class="com.mbalogos.mba.dao.AuditInterceptor" />

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
        <property name="entityInterceptor" ref="auditInterceptor"/>
    </bean>

    <bean id="namedQueryDao" class="com.mbalogos.mba.dao.NamedQueryDaoImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

И следующий entityInterceptor

public class AuditInterceptor extends EmptyInterceptor{

    /**
     * 
     */
    private static final long serialVersionUID = -8374988621501998008L;

    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state,
            String[] propertyNames, Type[] types) {
        if(entity instanceof DomainObject){
            Timestamp date = new Timestamp(new Date().getTime());
            ((DomainObject)entity).setCreationDate(date);
            ((DomainObject)entity).setModificationDate(date);
        }       
        return true;
    }

    @Override
    public boolean onFlushDirty(Object entity, Serializable id,
            Object[] currentState, Object[] previousState,
            String[] propertyNames, Type[] types) {
        if(entity instanceof DomainObject){
            DomainObject domainObject = (DomainObject)entity;
            Timestamp date = new Timestamp(new Date().getTime());
            domainObject.setModificationDate(date);             
        }
        return true;
    }

    @Override
    public void onDelete(Object entity, Serializable id, Object[] state,
            String[] propertyNames, Type[] types) {
        super.onDelete(entity, id, state, propertyNames, types);
    }

    @SuppressWarnings("rawtypes")
    @Override
    public void preFlush(Iterator entities) {
        super.preFlush(entities);
    }

    @SuppressWarnings("rawtypes")
    @Override
    public void postFlush(Iterator entities) {
        super.postFlush(entities);
    }
}

Следуя методу сохранения, sessionFactory вводится в класс

public <T extends DomainObject> T save(T objectToSave) {
    Session currentSession = null;
    try {
        currentSession = sessionFactory.getCurrentSession();
        currentSession.save(objectToSave);

        return objectToSave;
    } catch (Exception ex) {
        logger.error(ex);
    }
    return null;
}

Кто-нибудь имеет представление, почему происходит такое поведение. О, я также попытался поместить entityInterceptor в sessionFactory вместо transactionmanager, что было моей первой попыткой, то же самое поведение : (

2 6

2 ответа:

Мне удалось это выяснить, мне пришлось играть с именами свойств и их состояниями, а не с объектом сущности ... Странно, но зачем снабжать объект entity, если вы не можете играть с ним : (

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

@Override
public boolean onSave(Object entity, Serializable id, Object[] state,
        String[] propertyNames, Type[] types) {
    return audit(state, propertyNames);
}

private boolean audit(Object[] currentState, String[] propertyNames) {
    boolean changed = false;
    Timestamp timestamp = new Timestamp(new Date().getTime());
    for(int i=0;i<propertyNames.length;i++){
        if("creationDate".equals(propertyNames[i])){
            Object currentDate = currentState[i];
            if(currentDate == null){
                currentState[i] = timestamp;
                changed = true;
            }
        }

        if("modificationDate".equals(propertyNames[i])){
            currentState[i] = timestamp;
            changed = true;
        }
    }
    return changed;
}

Спасибо Кенни, я тоже столкнулся с той же проблемой. В моем случае перехватчики работают для некоторых сущностей, а для остальных они не работают.
Некоторые возможные оптимизации могут быть:
* Если вы закончили с поиском обоих свойств, то разорвите цикл.
* Если вы хотите применить метод аудита только с DomainObject, то отфильтруйте этот метод с помощью if(entity instanceof DomainObject)

До сих пор мне любопытно, почему установка атрибутов непосредственно на объект entity не работала для некоторых сущностей. Если вы или кто-нибудь другой знаете причину, тогда, пожалуйста, разместите его здесь.