2009-07-20 12 views
13

Ich habe diese beiden Klassen (Tabelle)Können zusätzliche Felder zur @ManyToMany-Hibernate-Zusatztabelle hinzugefügt werden?

@Entity 
@Table(name = "course") 
public class Course { 

    @Id 
    @Column(name = "courseid") 
    private String courseId; 
    @Column(name = "coursename") 
    private String courseName; 
    @Column(name = "vahed") 
    private int vahed; 
    @Column(name = "coursedep") 
    private int dep; 
    @ManyToMany(fetch = FetchType.LAZY) 
    @JoinTable(name = "student_course", joinColumns = @JoinColumn(name = "course_id"), inverseJoinColumns = @JoinColumn(name = "student_id")) 
    private Set<Student> student = new HashSet<Student>(); 
//Some setter and getter 

und diese ein:

@Entity 
    @Table(name = "student") 
    public class Student { 

     @Id 
     @Column(name="studid") 
     private String stId; 
     @Column(nullable = false, name="studname") 
     private String studName; 
     @Column(name="stmajor") 
     private String stMajor; 
     @Column(name="stlevel", length=3) 
     private String stLevel; 
     @Column(name="stdep") 
     private int stdep; 

     @ManyToMany(fetch = FetchType.LAZY) 
     @JoinTable(name = "student_course" 
       ,joinColumns = @JoinColumn(name = "student_id") 
       ,inverseJoinColumns = @JoinColumn(name = "course_id") 
     ) 
     private Set<Course> course = new HashSet<Course>(); 
//Some setter and getter 

Nach diesem Code eine zusätzliche Tabelle ausgeführt wurde, in der Datenbank (student_course) erstellt, jetzt will ich wissen, wie kann ich Extra-Feld in dieser Tabelle hinzufügen, wie (Grad, Datum und ... (I student_course Tabelle bedeuten)) ich eine Lösung finden, aber ich mag sie nicht, auch habe ich ein Problem mit ihnen:

First Sample

+0

Sie können eine zusätzliche Spalte mit \ @OrderColumn hinzufügen, die eine int-Spalte zum Speichern der Sortierreihenfolge einer many2many-Beziehung ist. Ich wünschte, sie würden eine \ @TempolalColumns hinzufügen, um ein fromDate und toDate Felder zu hinzufügen –

Antwort

16

Wenn Sie zusätzliche Felder in einer verknüpften Tabelle hinzufügen (STUDENT_COURSE), müssen Sie einen Ansatz gemäß der Antwort von skaffman oder einer anderen auswählen, wie unten gezeigt.

Es ist ein Ansatz, bei dem die verknüpfte Tabelle (STUDENT_COURSE) verhält sich wie ein @Embeddable nach:

@Embeddable 
public class JoinedStudentCourse { 

    // Lets suppose you have added this field 
    @Column(updatable=false) 
    private Date joinedDate; 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="STUDENT_ID", insertable=false, updatable=false) 
    private Student student; 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="COURSE_ID", insertable=false, updatable=false) 
    private Course course; 

    // getter's and setter's 

    public boolean equals(Object instance) { 
     if(instance == null) 
      return false; 

     if(!(instance instanceof JoinedStudentCourse)) 
      return false; 

     JoinedStudentCourse other = (JoinedStudentCourse) instance; 
     if(!(student.getId().equals(other.getStudent().getId())) 
      return false; 

     if(!(course.getId().equals(other.getCourse().getId())) 
      return false; 

     // ATT: use immutable fields like joinedDate in equals() implementation 
     if(!(joinedDate.equals(other.getJoinedDate())) 
      return false; 

     return true; 
    } 

    public int hashcode() { 
     // hashcode implementation 
    } 

} 

So werden Sie in beiden Schüler und Kurs Klassen haben

public class Student { 

    @CollectionOfElements 
    @JoinTable(
     [email protected](name="STUDENT_COURSE"), 
     [email protected](name="STUDENT_ID") 
    ) 
    private Set<JoinedStudentCourse> joined = new HashSet<JoinedStudentCourse>(); 

} 

public class Course { 

    @CollectionOfElements 
    @JoinTable(
     [email protected](name="STUDENT_COURSE"), 
     [email protected](name="COURSE_ID") 
    ) 
    private Set<JoinedStudentCourse> joined = new HashSet<JoinedStudentCourse>(); 

} 

erinnern: @ Der Lebenszyklus der einbettbaren Klasse ist an die besitzende Entitätsklasse (Student und Kurs) gebunden, also pass auf sie auf.

Hinweis: Das Hibernate-Team unterstützt diese beiden Ansätze (@ OneToMany (Skaffmans Antwort) oder @CollectionsOfElements) aufgrund einiger Einschränkungen im @ManyToMany-Mapping - Kaskadenbetrieb.

Grüßen,

+0

große Antwort.Wenn man nur eine Index-Spalte für die Zuordnung zu einer Liste braucht, kann man einfach @OrderColumn hinzufügen, obwohl – cproinger

+2

Wenn ich die obige Lösung ausprobiert habe, habe ich den Fehler 'Repeated column in mapping for collection' bekommen. Irgendeine Idee ? –

+0

Ich bekomme den gleichen Fehler wie Ankur Raiyani, meine Lösung ist der Skaffman. mit eingebetteter ID im Studentenkurs, um sicherzustellen, dass ich den richtigen Primärschlüssel für mich habe. Und dann entfernte ich den eingebetteten Schlüssel und warf eine @Id für jede ManToOne Relation –

7

Die Tabelle student_course dient nur dazu, die Verbindung zwischen den beiden Entitäten aufzuzeichnen. Es wird von Hibernate verwaltet und kann keine anderen Daten enthalten.

Die Art von Daten, die Sie aufzeichnen möchten, muss als eine andere Entität modelliert werden. Vielleicht könnten Sie eine Eins-zu-Viele-Verbindung zwischen Kurs und StudentResult (die die Note usw. enthält) und dann eine Viele-zu-Eins-Verbindung zwischen StendResult und Student.

+0

Tanx Mann Ich halte es für – Am1rr3zA

3

Löschen Sie die Viele-zu-Viele, erstellen Sie eine Klasse namens StudentCourseRelationship und richten Sie eine Manys auf Student und Course auf die StudentCourseRelationship ein.

Sie können alle möglichen Dinge auf sie setzen, wie DateEnrolled, DateKickedOut etc. etc.

IMO die many-to-many-Mapping ist ein bisschen ein con.

+0

Tanx Mann Ich halte es für – Am1rr3zA

+1

Wie wäre es mit DateGotToGripsWithAssociations? :) – skaffman

Verwandte Themen