18

Ich habe die folgenden Tabellen in meiner Datenbank:Composite-Key/ID-Mapping mit NHibernate

Announcements: 
- AnnouncementID (PK) 
- Title 

AnouncementsRead (composite PK on AnnouncementID and UserID): 
- AnnouncementID (PK) 
- UserID (PK) 
- DateRead 

Users: 
- UserID (PK) 
- UserName 

Normalerweise würde ich die "AnnouncementsRead" Karte eine many-to-many-Beziehung verwenden, aber diese Tabelle hat auch eine zusätzliche "DateRead" -Feld

Bisher habe ich definiert haben folgende Einrichtungen:

public class Announcement 
    { 
     public virtual int AnnouncementID { get; set; } 
     public virtual string Title { get; set; } 
     public virtual IList<AnnouncementRead> AnnouncementsRead { get; private set; } 

     public Announcement() 
     { 
      AnnouncementsRead = new List<AnnouncementRead>(); 
     } 
    } 

    public class AnnouncementRead 
    { 
     public virtual Announcement Announcement { get; set; } 
     public virtual User User { get; set; } 
     public virtual DateTime DateRead { get; set; } 
    } 

    public class User 
    { 
     public virtual int UserID { get; set; } 
     public virtual string UserName { get; set; } 
     public virtual IList<AnnouncementRead> AnnouncementsRead { get; private set; } 

     public User() 
     { 
      AnnouncementsRead = new List<AnnouncementRead>(); 
     } 
} 

Mit den folgenden Zuordnungen:

public class AnnouncementMap : ClassMap<Announcement> 
{ 
    public AnnouncementMap() 
    { 
     Table("Announcements"); 
     Id(x => x.AnnouncementID); 
     Map(x => x.Title); 
     HasMany(x => x.AnnouncementsRead) 
      .Cascade.All(); 
    } 
} 

public class AnnouncementReadMap : ClassMap<AnnouncementRead> 
{ 
    public AnnouncementReadMap() 
    { 
     Table("AnnouncementsRead"); 
     CompositeId() 
      .KeyReference(x => x.Announcement, "AnnouncementID") 
      .KeyReference(x => x.User, "UserID"); 
     Map(x => x.DateRead); 
    } 
} 

public class UserMap : ClassMap<User> 
{ 
    public UserMap() 
    { 
     Table("Users"); 
     Id(x => x.UserID); 
     Map(x => x.UserName); 
     HasMany(x => x.AnnouncementsRead) 
      .Cascade.All(); 
    } 
} 

aber wenn ich laufe dies ich die folgende Fehlermeldung:

"composite-id class must override Equals(): Entities.AnnouncementRead" 

Ich würde es begrüßen, wenn mir jemand in die richtige Richtung zeigen könnte. Danke

Antwort

7

Sie sollten genau das tun, was NHiberante Ihnen sagt. AnnouncementRead sollte die Methoden Equals und GetHashCode überschreiben. Sie sollten auf den Feldern basieren, die Teil des Primärschlüssels

0
  1. sind, wenn gleich der Umsetzung sollten Sie Verwendung Instanceof mit Subklassen Vergleich zu ermöglichen. Wenn Hibernate faul eine Eins-zu-Eins- oder Viele-zu-Eins-Beziehung lädt, haben Sie einen Proxy für die Klasse anstelle der einfachen Klasse. Ein Proxy ist eine Unterklasse. Ein Vergleich der Klassennamen würde fehlschlagen.
    Technisch: Sie sollten das Liskows Substitution-Prinzip befolgen und die Symmetrie ignorieren.
  2. Die nächste Fallstricke verwendet so etwas wie name.equals (that.name) anstelle von name.equals (that.getName()). Der erste wird fehlschlagen, wenn das ein Proxy ist.

http://www.laliluna.de/jpa-hibernate-guide/ch06s06.html

+0

Die Frage bezieht sich auf C# und NHibernate, Hibernate und Java nicht. Es gibt keine solche "instanceof", kein solches Problem wie '.name'-vs-' .getName'. Während Ihre Antwort im Allgemeinen OK ist und eine Person, die sowohl in C# als auch in Java erfahren wird, "die Konzepte" über Sprache/Plattformgrenze hinaus portieren kann. Allerdings gibt es nicht viele solche Leute, und das macht Ihre Antwort kaum brauchbar. – quetzalcoatl