2015-04-12 202 views
0

我只是試圖找出如何在Hibernate中映射下面的情況。休眠。如何將兩個多對多映射到同一個實體

有一些課程和一些學生。任何學生都有自己的學習計劃,其中包含可選課程和必修課程。

我很容易在數據庫世界中建模。我將有四個表:

  1. 場(ID,名稱,描述)
  2. 學生(ID,姓名)
  3. student_course_optional(student_id數據,COURSE_ID)
  4. student_course_required(student_id數據,COURSE_ID)

但我真的不知道如何映射這與休眠。

這裏我的第一稿:

@Entity 
public class Student { 

    private Long id; 
    private Long version; 
    private String name; 
    private List<Course> requiredCourses; 
    private List<Course> optionalCourses; 

    ... 

    @ManyToMany 
    @JoinTable(name="Course") 
    public List<Course> getRequiredCourses() { 
     return requiredCourses; 
    } 

    @ManyToMany 
    @JoinTable(name="Course") 
    public List<Course> getOptionalCourses() { 
     return optionalCourses; 
    } 
} 

@Entity 
public class Course { 

    private Long id; 
    private Long version; 
    private String name; 
    private List<Student> students; 
    private List<Student> optionalStudents; 

    ... 

    @ManyToMany(mappedBy="requiredCourses") 
    public List<Course> getStudents() { 
     return requiredCourses; 
    } 

    @ManyToMany(mappedBy="optionalCourses") 
    public List<Course> getOptionalStudents() { 
     return optionalCourses; 
    } 
} 

但不知何故,這看起來奇怪我。或者這是正確的?

+1

是否可以接受你改變數據庫模型一點:更換_student_course_optional_和_student_course_required_表與例如_student_course(student_id,course_id,可選)_? – wypieprz

+0

@wypieprz是的,它似乎更好:) – Tima

回答

1

示例實現可以使用中間實體,比如StudyPlan,其充當UML association class。這樣的實體包括:

  • StudyPlanId類表示的化合物主鍵
  • 通過studentcourse字段表示的外鍵(在JPA而言,這是一個衍生標識符
  • 附加由下式表示的狀態optional字段(它允許區分需求和可選課程)
@Entity 
@IdClass(StudyPlanId.class) 
public class StudyPlan { 
    @Id 
    @ManyToOne 
    private Student student; 

    @Id 
    @ManyToOne 
    private Course course; 

    private boolean optional; 
    ... 
} 
public class StudyPlanId implements Serializable { 
    private int course; 
    private int student; 

    @Override 
    public int hashCode() { ... } 
    @Override 
    public boolean equals(Object obj) { ... } 
    ... 
} 
@Entity 
public class Student { 
    @Id 
    private int id; 

    @OneToMany(mappedBy = "student") 
    private Collection<StudyPlan> plan; 

    private String name; 
    ... 
} 
@Entity 
public class Course { 
    @Id 
    private int id; 

    @OneToMany(mappedBy = "course") 
    private Collection<StudyPlan> plan; 

    private String name; 
    private String description; 
    ...  
} 

,上面的實體模型將產生以下數據模型:

Student   StudyPlan   Course 
=============== ================= =============== 
id   PK student_id FK PK id   PK 
name    course_id FK PK name  
        optional    description 
0
@ManyToMany(fetch = FetchType.EAGER) 
@JoinTable(name = "student_course_required", joinColumns = @JoinColumn(name = "student_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "course_id", referencedColumnName = "id")) 
private List<Course> requiredCourses= new ArrayList<Course>(); 

@ManyToMany(fetch = FetchType.EAGER) 
@JoinTable(name = "student_course_optional", joinColumns = @JoinColumn(name = "student_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "course_id", referencedColumnName = "id")) 
private List<Course> optionalCourses= new ArrayList<Course>(); 

Public Class Student需要更改爲up代碼。

@ManyToMany(fetch = FetchType.EAGER) 
@JoinTable(name = "student_course_required", joinColumns = @JoinColumn(name = "course_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "student_id", referencedColumnName = "id")) 
private List<Student> requiredStudents= new ArrayList<Student>(); 

@ManyToMany(fetch = FetchType.EAGER) 
@JoinTable(name = "student_course_optional", joinColumns = @JoinColumn(name = "course_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "student_id", referencedColumnName = "id")) 
private List<Student> optionalStudents= new ArrayList<Student>(); 

public Class Course需要更改爲up代碼。 我認爲這可以解決你的問題。