2009-07-20 8 views
11

J'utilise DDD et NHibernate pour conserver mon objet domaine. Dans ma base de données, chaque table liée à une entité comporte quatre colonnes supplémentaires (CreatedBy, UpdatedBy, CreatedDate, UpdatedDate) utilisées pour le suivi d'audit. J'utilise le modèle de référentiel qui permet uniquement d'enregistrer les racines agrégées. Lorsque NHibernate tente de sauvegarder les entités sur la racine agrégée, j'obtiens une erreur SQL DateTime car les propriétés d'audit des entités ne sont pas définies. Est-il possible dans NHibernate de définir des propriétés sur des objets juste avant la sauvegarde?NHibernate définir automatiquement les propriétés lors de la sauvegarde

Voici un petit exemple. J'ai un objet Order qui est la racine agrégée. J'ai aussi des objets OrderNote qui sont des enfants de la commande. Lorsque j'ajoute un OrderNote à l'ordre, puis que l'ordre est enregistré, une exception est levée, car CreatedDate/UpdatedDate est défini sur DateTime.MinValue, ce qui provoque un débordement SQL DateTime. Comme ces colonnes d'audit font partie de la persistance et ne sont pas liées au domaine du problème, je ne souhaite pas que la racine de l'agrégat Order définisse ces propriétés lorsque la note est ajoutée. Les colonnes/propriétés d'audit ne doivent être connues que par le framework de persistance et non par le domaine. Je voudrais pouvoir dire à NHibernate de définir ces propriétés lors de l'enregistrement ou de la mise à jour. Y a-t-il un moyen de faire cela?

Répondre

11

Interceptor peut faire:

http://www.nhforge.org/doc/nh/en/index.html#manipulatingdata-interceptors (9,10, lien ne fonctionne pas toujours).

Couper/coller du document:

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() pourrait être utilisé pour UpdatedDate.

Vous allez vouloir que chaque entité qui a un CreatedDate/UpdatedDate pour implémenter une interface afin que l'intercepteur puisse vérifier s'il doit agir (dans l'exemple fourni il est IAuditable).


Modifier

chapitre 11 remarqué simplement: intercepteurs et les événements. Vous pouvez hériter de EmptyInterceptor, ce qui facilite les choses si vous avez seulement besoin de surcharger certaines méthodes.

Je n'ai jamais utilisé d'événements.

+0

Excellent. C'est exactement ce que je cherche. Je suis nouveau à NHibernate et je ne connaissais pas cette fonctionnalité. J'ai une interface IAuditable implémentée avec des propriétés protégées afin que le domaine ne puisse pas les voir. – awilinsk

1

Vous pouvez également consulter le système de gestion des versions de NHibernate, qui peut vous aider dans votre cas;)