2012-09-23 18 views
7

Hallo bin ich die Winterschlaf Dokumentation zu lesen.Viele zu viele Hibernate inverse Seite ignoriert

http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html

Eine many-to-many-Vereinigung mit definiert ist logischerweise die @ManyToMany Anmerkung. Außerdem müssen Sie die Verknüpfungstabelle und die Verknüpfungsbedingungen mit der Annotation @JoinTable beschreiben. Wenn der Verein ist bidirektional, hat eine Seite der Eigentümer und eine Seite zu sein hat die inverse Ende sein (dh es wird ignoriert, wenn die Beziehung Werte in der Zuordnungstabelle zu aktualisieren.):

I versteh alles, aber die letzten

(dh. es wird ignoriert, wenn die Beziehung Werte in der Zuordnungstabelle aktualisieren).

Was bedeutet das? Beispiel?

Antwort

22

Angenommen, Sie die folgenden Entitäten:

@Entity 
public class Student { 
    @ManyToMany 
    private Set<Course> courses; 
    ... 
} 

@Entity 
public class Course { 
    @ManyToMany(mappedBy = "courses") 
    private Set<Student> students; 
    ... 
} 

Der Inhaber Seite: Student ist (weil es nicht das mappedBy Attribut hat). Die inverse Seite ist Platz ((weil es die mappedBy Attribut)

Wenn Sie Folgendes tun:.

Course course = session.get(Course.class, 3L); 
Student student = session.get(Student.class, 4L); 
student.getCourses().add(course); 

Hibernate einen Eintrag für Schüler 4 und Kurs 3 in der Join-Tabelle hinzugefügt werden, da Sie auf dem Laufenden Eigentümer Seite des Vereins (student.courses)

Während, wenn Sie wie folgt vorgehen:.

Course course = session.get(Course.class, 3L); 
Student student = session.get(Student.class, 4L); 
course.getStudents().add(student); 

nichts passieren wird, sein Ursache wurde die inverse Seite der Zuordnung aktualisiert (course.students), aber die Eigentümerseite wurde nicht aktualisiert. Hibernate berücksichtigt nur die Eigentümerseite.

+0

Thank you! Sehr gute Erklärung. Also ist der einzige Weg, den Besitzer zu aktualisieren? Beide Seiten können Eigentümer nicht sein, oder? Wie wenn ich möchte, dass es in beide Richtungen funktioniert? Nicht möglich? – pethel

+0

Ja, Sie müssen die Eigentümerseite aktualisieren. Nur eine Seite kann der Eigentümer sein. Es gibt keine Möglichkeit, es in beide Richtungen funktionieren zu lassen. –

+0

@ JBNizet, und was sagst du über die folgende Antwort? – azerafati

2

Um es auf beide Arten funktionieren zu lassen, müssen Sie zwei getrennte Beziehungen zwischen Ihren Entitäten haben. Dies kann durch eine Join-Tabelle in der Datenbank dargestellt werden, aber standardmäßig wird es durch zwei dargestellt, so dass Sie explizit sagen müssen, dass Sie eine Join-Tabelle wollen.

Ich werde es mit dem zuvor erwähnten Modell von Student und Kurs demonstrieren.

@Entity 
public class Student { 
    @ManyToMany 
    @JoinTable(name = "student_course", 
       joinColumns = {@JoinColumn(name = "courses_id")}, 
       inverseJoinColumns = {@JoinColumn(name = "students_id")}) 
    private Set<Course> courses; 
    ... 
} 

@Entity 
public class Course { 
    @ManyToMany 
    @JoinTable(name = "student_course", 
       joinColumns = {@JoinColumn(name = "students_id")}, 
       inverseJoinColumns = {@JoinColumn(name = "courses_id")}) 
    private Set<Student> students; 
    ... 
} 

Im obigen Beispiel haben wir 2 Beziehungen mit jeder Seite des Studenten < -> Kurs Beziehung zu dem Eigentümer einer Beziehung. So löst das Problem des Speicherns von Änderungen in der Datenbank nur auf der Seite des Besitzers, da jede Seite Besitzer einer Beziehung ist.

Aber wir dürfen nicht vergessen, eine Tatsache zu halten, dass die Daten nach dem Speichern, Beziehung Sammlungen werden nicht aus der Datenbank so Programmierern Notwendigkeit Beziehung neu geladen werden Sammlungen von sich selbst zu behandeln.Indem man sagt, dies möchte ich sagen, dass der einfachste Weg, um ist zu modifizieren Setter für Beziehung Sammlungen Zyklus zwischen Entitäten wie folgt neu zu erstellen:

public void setCourses(Set<Course> courses) { 
    for(Course c : courses) { 
     if (!c.getStudents().contains(this)) { 
      c.getStudents().add(this); 
     } 
    } 
    this.courses = courses; 
} 

public void setStudents(Set<Student> students) { 
    for(Student s : students) { 
     if (!s.getCourses().contains(this)){ 
      s.getCourses().add(this); 
     } 
    } 
    this.students = students; 
}