Ich habe schon seit ein paar Tagen mit einem NHibernate-Setup gekämpft und kann einfach nicht herausfinden, wie ich mein Mapping richtig einstellen soll, damit es so funktioniert, wie ich es mir vorstelle.
Es gibt ein bisschen Code, den ich durchlaufen muss, bevor ich zu den Problemen komme, daher entschuldige ich mich im Voraus für das zusätzliche Lesen.
Das Setup ist im Moment ziemlich einfach, mit nur diesen Tabellen:
Kategorie
KategorieId
Name
Artikel
Artikel-ID
Name
ItemCategory
Artikel-ID
Kategorieindikation
Ein Element kann in vielen Kategorien vorkommen und jede Kategorie kann viele Elemente enthalten (einfache Viele-zu-Viele-Beziehung).
Ich habe meine Zuordnung wie folgt festgelegt:
%Vor%Meine Methoden zum Hinzufügen von Elementen zur Objektliste in der Kategorie- und Kategorieliste in Objekt legen beide Seiten der Beziehung fest.
In Artikel :
%Vor%In Kategorie :
%Vor%Nun, das ist aus dem Weg, die Probleme, die ich habe, sind:
Wenn ich 'inverse="true"' aus dem Category.Items-Mapping entferne, erhalte ich doppelte Einträge in der Lookup-ItemCategory-Tabelle.
Wenn 'inverse="true"' verwendet wird, erhalte ich einen Fehler, wenn ich versuche, eine Kategorie zu löschen, da NHibernate den übereinstimmenden Datensatz nicht aus der Nachschlagetabelle löscht, also aufgrund der Fremdschlüsseleinschränkung fehlschlägt.
Wenn ich cascade="all" auf die Taschen setze, kann ich ohne Fehler löschen, aber das Löschen einer Kategorie löscht auch alle Elemente in dieser Kategorie.
Gibt es ein grundlegendes Problem mit der Art und Weise, wie ich mein Mapping eingerichtet habe, damit das Viele-zu-Viele-Mapping wie erwartet funktionieren kann?
Mit "so wie Sie es erwarten würden" meine ich, dass Löschvorgänge nichts mehr löschen als das gelöschte Element und die entsprechenden Nachschlagewerte (wobei das Element am anderen Ende der Beziehung unberührt bleibt) und Aktualisierungen für jede Sammlung aktualisiert die Nachschlagetabelle mit korrekten und nicht doppelten Werten.
Alle Vorschläge würden sehr geschätzt.
Was Sie tun müssen, damit Ihre Zuordnungen so funktionieren, wie Sie es erwarten würden, ist das Verschieben des inverse="true"
von der Category.Items
Sammlung in die Item.Categories
Sammlung. Auf diese Weise werden Sie NHibernate verstehen lassen, welche die besitzende Seite der Assoziation ist, und das wäre die "Category" -Seite.
Wenn Sie das tun, wird durch Löschen eines Category-Objekts der übereinstimmende Datensatz so aus der Nachschlagetabelle gelöscht, wie Sie möchten, da dies die besitzende Seite der Assoziation ist.
Um KEINE Elemente zu löschen, die einem Category-Objekt zugewiesen sind, das gelöscht werden soll, müssen Sie die Kaskadenattribute wie folgt lassen: cascade="save-update"
.
cascade="all"
löscht die Elemente, die dem gelöschten Category-Objekt zugeordnet sind.
Ein Nebeneffekt wäre jedoch, dass das Löschen der Entität auf der Seite, auf der die inverse = tru existiert, eine Fremdschlüsselverletzung auslöst, da der Eintrag in der Zuordnungstabelle nicht gelöscht wird.
Eine Lösung, bei der Ihre Zuordnungen genau so funktionieren, wie Sie möchten, dass sie funktionieren (anhand der Beschreibung, die Sie in Ihrer Frage angegeben haben), besteht darin, die Zuordnungstabelle explizit zuzuordnen. Ihre Abbildungen sollten so aussehen:
%Vor%Wie oben, können Sie Folgendes tun:
Alle oben genannten werden mit Komponententests getestet. Sie müssen die Klassenzuordnungsdatei und Klasse für die ItemCategory-Klasse erstellen, damit das oben genannte funktioniert.
Halten Sie die Sammlungen synchron? Hibernate erwartet von Ihnen, glaube ich, einen korrekten Objektgraph; Wenn Sie einen Eintrag aus Item.Categories löschen, müssen Sie den gleichen Eintrag aus Category.Items löschen, damit die beiden Sammlungen synchronisiert sind.
Tags und Links many-to-many nhibernate nhibernate-mapping