2015-04-12 3 views
0

Я просто попытаюсь выяснить, как сопоставить следующую ситуацию в Hibernate.Спящий режим. Как сопоставить два многого для одного и того же объекта

Есть несколько курсов и некоторые студенты. У любого учащегося есть собственный план обучения, содержащий дополнительные курсы и необходимые курсы.

Мне легко моделировать это в мире базы данных. Я бы четыре таблицы:

  1. курс (идентификатор, название, описание)
  2. Student (номер, имя)
  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 класса
  • внешний ключ представлен student и course полей (в терминах 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 необходимо изменить код.

@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 необходимо изменить код. Я думаю, что это может решить ваш вопрос.

Смежные вопросы