Quelles sont les erreurs les plus courantes et les programmeurs d'utilisateurs anti-modèles NHibernate?

28

Quelles sont les erreurs les plus courantes et les programmeurs d'utilisateurs anti-modèles NHibernate? Veuillez expliquer pourquoi ce sont de mauvaises pratiques ou donner un lien vers la ressource pour une lecture plus approfondie.

Par exemple:

  • Un anti-modèle commun aux nouveaux programmeurs NHibernate consiste à utiliser des POID d'identité / natifs au lieu d'onces de style ORM. En savoir plus ici ...
Darius Kucinskas
la source
1
Vous pouvez trouver certaines des erreurs les plus courantes ici: Alertes
1
Il y a aussi des articles précieux ici sur NHibernate Pitfalls

Réponses:

34

Mes problèmes personnels "fréquemment expliqués":

Anti-Patterns

Jouer avec des objets détachés (SaveOrUpdate ou Merge plus du code en désordre) au lieu d'utiliser des DTO. Plus les entités sont complexes, plus le code est compliqué. (Cela signifie également qu'il fonctionne assez bien avec des entités triviales.) Ayende l'appelle également le modèle de décapage et explique le problème d'encapsulation.

Ne pas comprendre l'ignorance de la persistance et écrire des applications NH comme lors de l'utilisation de SQL explicite. Symptôme: appeler Update après avoir changé un objet, se demander pourquoi les changements sont persistants même si Update n'a pas été appelé, se demander comment éviter que les changements soient persistants.

Ne pas comprendre les transactions et l' unité de travail . Anti-patterns fréquents: transactions implicites, session par opération et session par application. Un peu plus de lecture:

Utilisation d' événements NH pour intégrer la logique d'application (par exemple, suivi des modifications dans les déclencheurs d'insertion et de mise à jour)

Créez une classe par table . Certaines personnes ne comprennent pas OOD, d'autres ne comprennent pas la conception relationnelle.

Erreurs

utilisation de un à un au lieu de plusieurs à un. Je l'ai essayé d'expliquer dans cette réponse .

Utilisation de l' extraction de jointure en combinaison avec SetMaxResult. Mes dernières réponses liées à ce sujet:

Écriture d'entités auto-changeantes . Lorsqu'une entité ne retourne pas exactement la valeur qui avait été définie par NH, elle est considérée comme sale et est mise à jour à chaque session. Par exemple: remplacer la collection persistante NH dans un ensemble de propriétés.

  IList<Address> Addresses
  {
    get { return addresses; }
    // will cause the addresses collection to be built up from scratch
    // in the database in every session, even when just reading the entity.
    set { addresses = new List<Address>(value); }
  }

  int Whatever
  {
    // will make the entity dirty after reading negative values from the db.
    // this causes unexpected updates after just reading the entity.
    get { if (whatever < 0) return 0; }
    set { whatever = value; }
  }

Peut-être plus suit.

Stefan Steinegger
la source
2
+1: Vous devez ajouter "Ne pas utiliser le modèle d'unité de travail" et "Une session par application" à votre liste à mon humble avis.
Falcon
@Falcon: oui probablement. C'est un problème général de "ne pas comprendre les transactions". L'unité de travail est un peu couverte par l'ignorance persistante. Bien qu'il s'agisse de concepts complètement différents, ils aboutissent aux mêmes modèles.
Stefan Steinegger
5

Le " problème N + 1 ".

C'est là que vous finissez par exécuter une sélection pour chaque entité que vous souhaitez manipuler (N) et une sélection pour obtenir la liste des entités (+1), au lieu d'une seule sélection de toutes les entités et de leurs attributs.

Sean McMillan
la source
1
  • Trop d'abstractions
  • Ne pas utiliser les mappages automatiques avec FluentNHibernate
Sournois
la source
Le premier point est un peu vague, mais au cas où vous faites référence à des notions idiotes telles que cacher ISession derrière un "référentiel" ou "DAO", je suis d'accord.
chris
1
Le deuxième point est cependant un non-sens. Il y a de bonnes raisons pour lesquelles nous voulons souvent avoir un contrôle fin sur le modèle de données physiques et pouvoir le dissocier du modèle de domaine. Après tout, c'est le but du "M" dans "ORM". L'utilisation de mappages automatiques (bien qu'utile dans des scénarios simples) va à l'encontre de cela. En outre, il y a également le problème des schémas d'intégration de la base de données hérités, pour lesquels le mappage automatique est inutile.
chris
J'utilise le mappage intégré par convention de code. Il gère une grande bande de merde que je devrais sinon répéter. Cependant, il offre toujours la liberté de personnalisation spécifique à l'entité qui est superposée au mappage généré par la convention. C'est super utile.
Sam
1

Essayer de l'abstraire afin de pouvoir basculer vers Entity Framework (ou autre chose) à une date ultérieure.

C'est beaucoup, beaucoup plus difficile que la plupart des gens qui tentent de le réaliser. Il existe de nombreuses différences entre les deux qui peuvent vous faire trébucher de manière parfois subtile. Il est également très rare qu'il soit finalement nécessaire - à tel point que vous pouvez méticuleusement essayer de le mettre en œuvre pendant des années avant de découvrir que votre approche est tout à fait erronée.

En outre, cela vous empêche d'utiliser un grand nombre de fonctionnalités utiles et importantes de NHibernate telles que la mise en cache de deuxième niveau, l'interception, la gestion des accès concurrents, le suivi des modifications, les requêtes de prélecture, etc.

S'il y avait vraiment un besoin valable de basculer entre NHibernate et Entity Framework, il y aurait un projet activement développé pour le prendre en charge sur GitHub (peut-être quelque chose dans la même veine que CommonServiceLocator) avec de nombreux contributeurs et demandes de tirage.

confitures
la source