2009-07-20 37 views
13

Tôi có hai lớp (bảng)Có thể thêm các trường bổ sung vào bảng bổ sung @ManyToMany Hibernate không?

@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 

và một này:

@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 

Sau khi chạy đoạn mã này một bảng phụ đã được tạo ra trong cơ sở dữ liệu (student_course), bây giờ tôi muốn biết làm thế nào tôi có thể thêm trường bổ sung trong bảng này như (Lớp, Ngày và ... (Tôi có nghĩa là bảng student_course)) Tôi thấy một số giải pháp nhưng tôi không thích chúng, Ngoài ra tôi có một số vấn đề với chúng:

First Sample

+0

Bạn có thể thêm một cột phụ bằng cách sử dụng \ @OrderColumn là cột int được sử dụng để lưu trữ thứ tự sắp xếp của mối quan hệ nhiều2many. Tôi muốn họ sẽ thêm một \ @TempolalColumns để thêm một trường fromDate và toDate quá –

Trả lời

16

Nếu bạn thêm các trường bổ sung trên bảng được nối kết (STUDENT_COURSE), bạn phải chọn phương pháp theo câu trả lời của người thu thập dữ liệu hoặc câu hỏi khác như được hiển thị bên dưới.

Có một cách tiếp cận nơi bảng liên kết (STUDENT_COURSE) hoạt động như một @Embeddable theo:

@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 
    } 

} 

Vì vậy, bạn sẽ có trong cả hai lớp sinh viên và học

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>(); 

} 

nhớ: @ Lớp có thể nhúng có vòng đời của nó được ràng buộc với lớp thực thể sở hữu (cả Sinh viên và Khóa học), vì vậy hãy quan tâm đến nó.

tư vấn: Nhóm Hibernate cho phép hai phương pháp này (@OneToMany (câu trả lời của người thu thập) hoặc @CollectionsOfElements) do một số hạn chế trong ánh xạ @ManyToMany - hoạt động xếp tầng.

regards,

+0

câu trả lời tuyệt vời.nếu chỉ cần một cột chỉ mục để ánh xạ tới một Danh sách, bạn chỉ có thể thêm @OrderColumn mặc dù – cproinger

+2

Khi tôi đã thử giải pháp trên, tôi nhận được 'cột Lặp lại trong ánh xạ cho lỗi bộ sưu tập'. Bất kỳ ý tưởng ? –

+0

Tôi nhận được lỗi giống như Ankur Raiyani, giải pháp của tôi là skaffman. sử dụng id được nhúng trong học sinh để đảm bảo rằng tôi có đúng khóa chính đang diễn ra cho tôi. Và sau đó tôi gỡ bỏ khóa nhúng và ném một @Id cho mỗi mối quan hệ manToOne –

7

Bảng student_course hoàn toàn có thể ghi lại liên kết giữa hai thực thể. Nó được quản lý bởi hibernate, và có thể chứa không có dữ liệu khác.

Loại dữ liệu bạn muốn ghi cần được mô hình hóa như một thực thể khác. Có lẽ bạn có thể liên kết một-nhiều giữa Khóa học và StudentResult (trong đó có điểm, vv), và sau đó là một mối liên hệ nhiều-một giữa StdentResult và Sinh viên.

+0

Tanx man Tôi xem xét nó – Am1rr3zA

3

Thả nhiều người thành nhiều lớp, tạo một lớp có tên là StudentCourseRelationship và thiết lập một đến nhiều lớp học về Sinh viên và Khóa học cho StudentCourseRelationship.

Bạn có thể đặt tất cả các loại vật trên nó, như DateEnrolled, DateKickedOut vv vv

IMO ánh xạ nhiều-nhiều là một chút của một con.

+0

Tanx man Tôi xem xét nó – Am1rr3zA

+1

Làm thế nào về DateGotToGripsWithAssociations? :) – skaffman

2

Câu trả lời được chấp nhận không may không làm việc cho tôi, Hibernate tạo ra các bảng tham gia trong một cách kỳ lạ (tất cả tham gia các cột được nhân đôi). Tuy nhiên các biến thể với thực thể chuyên dụng cho bảng tham gia hoạt động tốt. Ở đây nó được mô tả chi tiết tuyệt vời: http://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/

Các vấn đề liên quan