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 ответа:
Мне удалось это выяснить, мне пришлось играть с именами свойств и их состояниями, а не с объектом сущности ... Странно, но зачем снабжать объект 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 не работала для некоторых сущностей. Если вы или кто-нибудь другой знаете причину, тогда, пожалуйста, разместите его здесь.