2012-07-31 81 views
4

我正在使用spring配置的hibernate应用程序。有transactionmanagement和一个auditInterceptor定义为entityInterceptor。当我调试的代码,我进入entityInterceptors方法和日期的被设置,但是在的结束时,保存他们不是在数据库:(。Hibernate实体拦截器触发但设置值不保存

考虑以下配置

<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,同样的行为:(

回答

9

我设法弄明白了,我不得不使用属性名和它们的状态,而不是实体对象。 ..奇怪为什么虽然在提供实体对象,如果你不能发挥与它:(

@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; 
} 
0

感谢肯尼,我也面临同样的问题。对我来说,拦截正在为一些实体,为休息,他们不工作
一些可能的优化可能是:
*如果你已经完成搜索正确关系,然后打破循环。
*如果你想只的domainObject然后用if(entity instanceof DomainObject)

过滤将该方法应用于审计方法,不过我很好奇,为什么设置属性直接实体对象是不工作的一些实体。如果您或任何人知道原因,请在此处张贴。

+0

欢迎你,很高兴它帮助你 – kenny 2012-11-23 14:38:35