2009-07-20 16 views
11

Estoy usando DDD y NHibernate para conservar mi objeto de dominio. En mi base de datos, cada tabla que está relacionada con una entidad tiene cuatro columnas adicionales (CreatedBy, UpdatedBy, CreatedDate, UpdatedDate) utilizadas para el seguimiento de la auditoría. Estoy usando el patrón de repositorio que solo permite que se guarden las raíces agregadas. Cuando NHibernate intenta guardar las entidades en la raíz agregada, obtengo un error SQL DateTime porque las entidades no tienen establecidas sus propiedades de auditoría. ¿Hay alguna forma en NHibernate de establecer propiedades en objetos justo antes de guardar?NHibernate establece las propiedades automáticamente al guardar

Aquí hay un pequeño ejemplo. Tengo un objeto Order que es la raíz agregada. También tengo objetos OrderNote que son hijos de la orden. Cuando agrego una nota de pedido al pedido y luego guardo el pedido, se lanza una excepción porque CreatedDate/UpdatedDate están configurados en DateTime.MinValue, lo que provocará un desbordamiento de DateTime de SQL. Dado que estas columnas de auditoría son parte de la persistencia y no están relacionadas con el dominio del problema, no deseo que la raíz del agregado de Order establezca estas propiedades cuando se agrega la nota. Las columnas/propiedades de auditoría solo deben conocerse mediante el marco de persistencia y no el dominio. Me gustaría poder decirle a NHibernate que establezca estas propiedades al guardarlas o actualizarlas. ¿Hay alguna forma de hacer esto?

Respuesta

11

interceptores pueden hacer esto:

http://www.nhforge.org/doc/nh/en/index.html#manipulatingdata-interceptors (9,10, enlace no siempre funciona).

cortar/pegar desde el documento:

public class AuditInterceptor : IInterceptor 
{ 
    ... 

    public boolean OnSave(object entity, 
          object id, 
          object[] state, 
          string[] propertyNames, 
          IType[] types) 
    { 
     if (entity is IAuditable) 
     { 
      for (int i=0; i<propertyNames.Length; i++) 
      { 
       if ("CreateTimestamp" == propertyNames[i]) 
       { 
        state[i] = DateTime.Now; 
        return true; 
       } 
      } 
     } 
     return false; 
    } 

} 

OnFlushDirty() podría ser utilizado para UpdatedDate.

Va a desear que todas las entidades que tengan un CreatedDate/UpdatedDate implementen una interfaz para que el interceptor pueda verificar si debe actuar (en el ejemplo proporcionado es IAuditable).


Editar

Sólo notado el capítulo 11: Interceptores y eventos. Puede heredar de EmptyInterceptor lo que facilita las cosas si solo tiene que anular algunos de los métodos.

Nunca he usado Eventos.

+0

Genial. Eso es exactamente lo que estoy buscando. Soy nuevo en NHibernate y no estaba al tanto de esta característica. Tengo una interfaz IAuditable implementada con propiedades protegidas para que el dominio no pueda verlas. – awilinsk

1

También puede consultar el sistema de control de versiones de NHibernate, que puede ayudarlo en su caso;)

Cuestiones relacionadas