Comment empêcher l'écriture de modifications d'objet dans la base de données avec Flush with Castle ActiveRecord / NHibernate

StackOverflow https://stackoverflow.com/questions/310286

Question

Le comportement par défaut de NHibernate est l'écriture de toutes les modifications apportées aux objets dans la base de données lors de l'appel de Session.Flush (). C’est ce que vous le vouliez ou non.

Comment empêcher l'écriture de données incorrectes dans la base de données lorsque nous devons effectuer des tâches telles que la validation des règles commerciales ou la saisie?

Par exemple ..

  • Le nom du client n'est pas nul.
  • L'utilisateur ouvre un navigateur Web (sans javascript) et supprime le nom du client.
  • Hits update.
  • La propriété
  • Customer.Name est mise à jour et ..
  • Customer.IsValid () est appelé.
  • Même si IsValid () est false et que nous affichons des messages d'erreur, NHibernate met toujours à jour la base de données.
Était-ce utile?

La solution

Spécifiquement pour ActiveRecord: si vous ne modifiez pas vous-même SessionScope, AR utilise par défaut un modèle de gestion de session session par appel, dans lequel une nouvelle session est créée pour chaque opération d'ActiveRecordMediator. Ainsi, tous les objets que vous récupérez sont déjà déconnectés de leur session parent une fois que vous les avez récupérés. Les modifications ne seront pas persistées jusqu'à ce que / sauf si vous appelez Save (ou SaveAndUpdate, ou même Update) qui, dans un modèle de session par appel, créera une session, joindra l'objet que vous enregistrez à cette session, appelez Save et puis disposer de la session (provoquant un Flush et donc l'écriture des modifications).

Lorsque vous utilisez AR de cette façon, il fait exactement ce que vous semblez vouloir (c’est-à-dire qu’aucune modification n’est écrite à moins que vous n’appeliez explicitement Save). Mais cela va explicitement à l’encontre du comportement attendu de NHibernate et vous ne pouvez pas charger paresseux ni tirer beaucoup d’utilisation de la mise en cache. J'ai utilisé ce modèle pour certaines applications Web, mais elles sont conçues à l'avance pour être chargées rapidement et bon nombre des objets persistants sont effectivement immuables et statiques et peuvent être chargés en masse au démarrage et mis en cache sans connexion à aucun session. Si votre application ne convient pas à ce modèle, alors session par appel est probablement une mauvaise idée.

Étant donné que vous semblez utiliser un modèle UOW, vous ne pouvez pas tirer parti de ce comportement. Ainsi, vous devez soit expulser l'objet de la session NHibernate (et obtenir un accès à l'instance réelle d'ISession n'est en réalité pas aussi facile qu'il y paraît dans AR), soit modifier le fonctionnement de votre application afin que les propriétés des objets persistants ne soient pas modifiées. jusqu'à ce que vos règles commerciales aient été validées.

Autres conseils

Utilisez la méthode ISession.Evict (objectToEvict) pour supprimer les objets non valides.

Voir: http://www.tobinharris.com/2007/2 / 3 / nhibernate-faq et http://www.surcombe.com/nhibernate-1.2/api/ html / M_NHibernate_ISession_Evict.htm

  

Le comportement par défaut de NHibernate est l'écriture de toutes les modifications apportées aux objets dans la base de données lors de l'appel de Session.Flush (). C’est ce que vous le vouliez ou non.

Si vous ne souhaitez pas que NHibernate purge la session, pourquoi lui demandez-vous de vider la session? Flush () est un raccourci pour WriteAllChangesToObjectsToTheDatabase () .

  

Comment empêcher l'écriture de données incorrectes dans la base de données lorsque nous devons effectuer des tâches telles que la validation des règles commerciales ou la saisie?

  • Validez les modifications avant avant de modifier les objets du modèle. N'autorisez pas les objets de modèle non valides à exister en mémoire (du point de vue de l'API publique exposée par votre modèle et en excluant les scénarios multithreads).
  • Emballez vos modifications dans une transaction, qui échouera si la validation de vos objets modèle échoue (pourquoi autorisez-vous les objets modèles non valides?).

Donc, je sais que c’est complètement exagéré, mais voici comment je l’ai corrigé.

Converti en NHibernate 2.0 et utilisé le projet NHibernate Validator pour exécuter mes règles de validation des entrées. Je n'ai pas encore géré les règles de gestion, mais je pense pouvoir les appliquer avec des règles de validation personnalisées. Si cela ne fonctionne pas, je peux utiliser les événements nhibernate.

Comme j’utilisais déjà le modèle de référentiel, la conversion était incroyablement simple. Cela a pris environ 4-5 heures et notre modèle est assez étendu. Pouvoir générer les fichiers .xml à partir des attributs AR a permis d’économiser beaucoup de temps.

Vous pouvez également utiliser une session avec FlushAction.Never. C'est à dire:

SessionScope session = new SessionScope(FlushAction.Never);

Ceci changera le comportement par défaut de l'enregistrement automatique de tout ce qui vous est explicitement nécessaire d'appeler .Save () sur vos entités. Vous pouvez donc valider ce que vous devez faire et ne sauvegarder que ce que vous voulez ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top