Was sind die häufigsten Fehler und Anti-Patterns, die Anwenderprogrammierer von NHibernate machen?

28

Was sind die häufigsten Fehler und Anti-Patterns, die Anwenderprogrammierer von NHibernate machen? Bitte erläutern Sie, warum dies schlechte Praktiken sind, oder geben Sie einen Link zu einer Ressource, die Sie weiterlesen können.

Beispielsweise:

  • Ein für neue NHibernate-Programmierer übliches Anti-Pattern ist die Verwendung von Identity / Native POIDs anstelle von ORM-Style-Onces. Lesen Sie hier mehr ...
Darius Kucinskas
quelle
1
Einige der häufigsten Fehler finden Sie hier: NHProf Alerts
1
Außerdem gibt es hier einige wertvolle Beiträge über NHibernate Pitfalls

Antworten:

34

Meine persönlichen "häufig erklärten" Probleme:

Anti-Patterns

Spielen Sie mit losgelösten Objekten (SaveOrUpdate oder Merge plus etwas chaotischen Code) herum, anstatt DTOs zu verwenden. Je komplexer die Entitäten sind, desto chaotischer ist der Code. (Dies bedeutet auch, dass es mit trivialen Entitäten recht gut funktioniert.) Ayende nennt es auch das Stripper-Muster und erklärt das Verkapselungsproblem.

Nicht verstehen, Persistenz Ignoranz und Schreiben von NH-Anwendungen wie bei der Verwendung von explizitem SQL. Symptom dafür: Aufrufen von Update nach dem Ändern eines Objekts. Fragen Sie sich, warum Änderungen beibehalten werden, auch wenn Update nicht aufgerufen wurde. Fragen Sie sich, wie Sie verhindern können, dass Änderungen beibehalten werden.

Nicht verstehen, Transaktionen und die Einheit des Arbeitsmusters . Häufige Antimuster: implizite Transaktionen, Sitzung pro Operation und Sitzung pro Anwendung. Noch etwas lesen:

Verwenden von NH- Ereignissen zum Einfügen von Anwendungslogik (z. B. Änderungsnachverfolgung in Einfüge- und Aktualisierungs-Triggern)

Erstellen Sie eine Klasse pro Tabelle . Einige Leute verstehen OOD nicht, andere verstehen relationales Design nicht.

Fehler

Verwendung von eins zu eins anstelle von vielen zu eins. Ich versuchte es in dieser Antwort zu erklären .

Verwenden von Join-Abruf in Kombination mit SetMaxResult. Meine neuesten Antworten zu diesem Thema:

Selbstverändernde Entitäten schreiben . Wenn eine Entität den von NH festgelegten Wert nicht genau zurückgibt, gilt sie als fehlerhaft und wird in jeder Sitzung aktualisiert. Beispiel: Ersetzen der persistenten NH-Sammlung in einem Eigenschaftssetter.

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

Vielleicht folgt noch mehr.

Stefan Steinegger
quelle
2
+1: Sie sollten Ihrer Liste imho "Keine Arbeitseinheit verwenden" und "Eine Sitzung pro Anwendung" hinzufügen.
Falcon
@ Falcon: Ja, wahrscheinlich. Dies ist ein allgemeines Problem, bei dem Transaktionen nicht verstanden werden. Die Arbeitseinheit ist ein bisschen von Beharrlichkeitsunwissenheit bedeckt. Obwohl es sich um völlig unterschiedliche Konzepte handelt, führen sie zu denselben Mustern.
Stefan Steinegger
5

Das " Select N + 1 Problem ".

Hier führen Sie eine Auswahl für jedes Objekt aus, das Sie bearbeiten möchten (N), und eine Auswahl, um die Liste der Objekte (+1) zu erhalten, anstatt eine einzige Auswahl aller Objekte und ihrer Attribute.

Sean McMillan
quelle
1
  • Zu viele Abstraktionen
  • Verwenden Sie keine Automappings mit FluentNHibernate
Schlau
quelle
Der erste Punkt ist ein wenig vage, aber wenn Sie sich auf dumme Begriffe beziehen, wie das Verstecken von ISession hinter einem "Repository" oder "DAO", stimme ich zu.
Chris
1
Der zweite Punkt ist jedoch Unsinn. Es gibt gute Gründe, warum wir häufig eine differenzierte Kontrolle über das physische Datenmodell haben und dieses vom Domänenmodell entkoppeln möchten. Immerhin ist das der Punkt des "M" in "ORM". Die Verwendung von Automappings (während dies in einfachen Szenarien nützlich ist) beseitigt dies. Daneben gibt es auch das Problem der Integration älterer Datenbankschemata, für die die automatische Zuordnung unbrauchbar ist.
Chris
Ich benutze das eingebaute, auf Codekonventionen basierende Mapping. Es geht um eine Menge Mist, den ich sonst wiederholen müsste. Sie bietet jedoch weiterhin die Freiheit, die Zuordnung, die durch die Konvention generiert wird, entitätsspezifisch anzupassen. Es ist super hilfreich.
Sam
1

Versuchen Sie es zu abstrahieren, damit Sie zu einem späteren Zeitpunkt zu Entity Framework (oder etwas anderem) wechseln können.

Das ist viel, viel schwieriger als die meisten Menschen, die es versuchen, zu realisieren. Es gibt zahlreiche Unterschiede zwischen den beiden, die Sie in einer Weise stolpern können, die manchmal sehr subtil sein kann. Es ist auch sehr ungewöhnlich, dass es am Ende tatsächlich benötigt wird - so sehr, dass Sie jahrelang sorgfältig versuchen können, es umzusetzen, bevor Sie feststellen, dass Ihr Ansatz völlig falsch ist.

Darüber hinaus können Sie nicht viele nützliche und wichtige Funktionen von NHibernate nutzen, z. B. Zwischenspeichern auf zweiter Ebene, Abfangen, Parallelitätsverwaltung, Änderungsverfolgung, Vorablesezugriffsabfragen usw.

Wenn es wirklich notwendig wäre, zwischen NHibernate und Entity Framework umzuschalten, gäbe es ein aktiv entwickeltes Projekt, um dies auf GitHub (möglicherweise ähnlich wie CommonServiceLocator) mit zahlreichen Mitwirkenden und Pull-Anfragen zu unterstützen.

Marmeladenkuchen
quelle