【问题标题】:Hibernate. How to map two many-to-many to the same entity休眠。如何将两个多对多映射到同一个实体
【发布时间】:2015-04-12 20:58:45
【问题描述】:

我只是试图找出如何在 Hibernate 中映射以下情况。

有一些课程和一些学生。任何学生都有自己的学习计划,包括选修课和必修课。

对我来说,在数据库世界中对此进行建模看起来很容易。我会有四张桌子:

  1. 课程(ID、名称、描述)
  2. 学生(身份证、姓名)
  3. student_course_optional (student_id, course_id)
  4. student_course_required (student_id, course_id)

但我真的不知道如何用 hibernate 映射它。

这是我的初稿:

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

但这对我来说看起来很奇怪。或者这样说对吗?

【问题讨论】:

  • 您是否可以稍微更改数据库模型:将 student_course_optionalstudent_course_required 表替换为例如student_course(student_id, course_id, optional) ?
  • @wypieprz 是的,它似乎更好:)

标签: hibernate


【解决方案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

【讨论】:

    【解决方案2】:
    @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需要更改代码。

     @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需要更改代码。 我认为这可以解决您的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-11
      • 2018-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-22
      • 2022-01-23
      • 1970-01-01
      相关资源
      最近更新 更多