by Oliver
15. January 2010 14:16
Einige Zeit nun schon wurmte mich, dass immer, wenn ein User-Objekt von NHibernate geladen wurde, direkt im Anschluss ein UPDATE geschah. Offensichtlich sind die Objekt also dirty, obwohl wissentlich nichts mit ihnen passiert ist.
Unter folgendem Link fand ich gestern auf nhforge eine Möglichkeit für eine nähere Inspektion des Problems, genauer des verschmutzten Objekts. Mit dem dort befindlichen Code und einer kleinen zusätzlichen Methode kann man nun wie folgt gezielt Objekte und deren Properties auf Veränderung prüfen:
1: private void FindDirtyMembers(User user)
2: {
3: var session = _nHibernateHelper.Session;
4:
5: Console.WriteLine("Entity {0}#{1} is dirty: {2}", user.Type, user.Id,
6: session.IsDirtyEntity(user));
7:
8: var dirtyPropNames = session.GetDirtyPropertyNames(user);
9:
10: foreach (var propName in dirtyPropNames)
11: {
12: var original = session.GetOriginalEntityProperty(user, propName);
13: Console.WriteLine("Property '{0}' is dirty! Original: {1}", propName, original);
14: }
15: }
Die Extension-Methods für die Session habe ich in SpeakLib.Utilities\Persistance.NHibernate\SessionExtensions.cs abgelegt.
Mit diesem Check bekam ich beim ersten Test dann auf der Console auch sofort den Fehler zu sehen:
1: Entity UserCampingInfo#1 is dirty: True
2: Property 'MaritalStatus' is dirty! Original: Unspecified
Und tatsächlich steht im Mapping-File für MaritalStatus ein falscher (Enum) Typ:
1: <property name="MaritalStatus" type="SpeakFriend.Utilities.Gender, SpeakFriend.Utilities" />
2:
Was macht NHibernate an dieser Stelle? Ich denke, NH baut ein enum vom Typ Gender zusammen und weist es der Property MaritalStatus zu – wobei dieses dann implizit in den Typen MaritalStatus um. Und das führt dazu, dass das Objekt direkt nach dem Laden dirty ist. Lösung ist also die Anpassung des Mappings auf den richtigen Enum-Typen.
1: <property name="MaritalStatus" type="SpeakFriend.Utilities.MaritalStatus, SpeakFriend.Utilities" />
2:
Gruß, Oliver