Wie überprüfen Sie die eindeutige Integritätsverletzung in nHibernate und DDD vor dem Speichern?

8

Ich habe ein Kontomodellobjekt und eine UNIQUE-Einschränkung für den Namen des Kontos. Wie sollte ich in Domain Driven Design mit nHibernate nach der Unicity des Namens suchen, bevor eine Entität eingefügt oder aktualisiert wird?

Ich möchte mich nicht auf eine nHibernate-Ausnahme verlassen, um den Fehler zu erkennen. Ich möchte meinem Benutzer eine schönere Fehlermeldung zurückgeben als das obskure could not execute batch command.[SQL: SQL not available]

In der Frage Wo sollte ich einen eindeutigen Check-in vornehmen? DDD? , jemand schlug vor, eine Spezifikation so zu verwenden.

%Vor%

mit dem Spezifikationscode als:

%Vor%

Dies funktioniert bei Einfügungen, aber nicht bei einem Update, weil. Ich habe versucht, den Code zu ändern:

%Vor%

Das Problem ist, dass nHibernate ein Update für die Datenbank ausgibt, wenn es GetAccountByName() ausführt, um ein mögliches Duplikat wiederherzustellen ...

%Vor%

Also, was soll ich tun? Ist die Spezifikation nicht der richtige Weg?

Danke für Ihre Gedanken!

    
dstj 06.10.2011, 16:15
quelle

2 Antworten

5

Ich bin kein Fan des Spezifikationsmusters für den Datenzugriff, es scheint immer so zu sein, als würde man springen, um etwas zu erledigen.

Aber was Sie vorgeschlagen haben, was wirklich nur darauf hinausläuft:

  1. Überprüfen Sie, ob es bereits existiert.
  2. Hinzufügen, wenn nicht; Zeigen Sie eine benutzerfreundliche Nachricht, wenn dies der Fall ist.

... ist so ziemlich der einfachste Weg, um es zu erledigen.

Sich auf Datenbankausnahmen zu verlassen, ist eine andere Möglichkeit, wenn Ihre Datenbank und ihr .NET-Client die Tabelle & amp; Spalte (n), die die eindeutige Einschränkung verletzen. Ich glaube, dass die meisten Fahrer das nicht tun (??), da sie einfach eine generische ConstraintException werfen, die besagt, dass "Constraint XYZ in der Tabelle ABC verletzt wurde". Sie können natürlich eine Konvention für Ihre eindeutige Constraint-Benennung haben, um etwas wie UK_MyTable_MyColumn zu sagen und String-Magie zu verwenden, um den Table & amp; Spaltennamen aus.

NHibernate hat eine ISQLExceptionConverter , die Sie in das Objekt Configuration einfügen können, wenn Sie NHibernate aktivieren. Darin werden Sie von dem .NET-Datenclient auf die Ausnahme hingewiesen. Sie können diese Ausnahme verwenden, um die Tabelle & amp; Spalten (möglicherweise unter Verwendung des Constraint-Namens?) und eine neue Exception mit einer benutzerfreundlichen Nachricht auslösen.

Die Verwendung der Datenbankausnahmemethode ist leistungsfähiger, und Sie können eine große Menge des Erkennungs-eindeutigen-Einschränkungs-Verstoß -Codes auf die Infrastrukturebene verschieben, anstatt jede einzelne von Fall zu Fall zu behandeln.

Eine weitere Sache, die mit der Methode query-first-then-add hervorgehoben werden sollte, ist, dass Sie, um vollständig transaktionssicher zu sein, die Transaktionsebene auf serializable (was die schlechteste Nebenläufigkeit ergibt) eskalieren müssen absolut kugelsicher sein. Ob Sie vollständig kugelsicher sein müssen oder nicht, hängt von Ihren Anwendungsanforderungen ab.

    
Thilak Nathen 06.10.2011, 21:47
quelle
-2

Sie müssen es mit dem Session.FlushMode-Modus behandeln, um auf FlushMode.Commit zu setzen und die Transaktion zum Rollback zu verwenden, wenn überhaupt ein Update ausgelöst wird.

    
Sathish Naga 06.10.2011 19:57
quelle