Можно ли добавить дополнительные поля в дополнительную таблицу @ManyToMany Hibernate? - PullRequest
14 голосов
/ 20 июля 2009

У меня есть эти два класса (таблица)

@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

и этот:

    @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

После выполнения этого кода в базе данных была создана дополнительная таблица (student_course), теперь я хочу знать, как добавить дополнительное поле в эту таблицу, например (Grade, Date и ... (я имею в виду таблицу student_course)) Я вижу какое-то решение, но они мне не нравятся, также у меня есть некоторые проблемы с ними:

Первый образец

Ответы [ 4 ]

16 голосов
/ 23 июля 2009

Если вы добавляете дополнительные поля в связанную таблицу (STUDENT_COURSE), вы должны выбрать подход в соответствии с ответом скаффмана или другим, как показано ниже.

Существует подход, при котором связанная таблица (STUDENT_COURSE) ведет себя как @Embeddable согласно:

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

}

Таким образом, вы будете иметь в классах и студентов, и курсов

public class Student {

    @CollectionOfElements
    @JoinTable(
        table=@Table(name="STUDENT_COURSE"),
        joinColumns=@JoinColumn(name="STUDENT_ID")
    )
    private Set<JoinedStudentCourse> joined = new HashSet<JoinedStudentCourse>();

}

public class Course {

    @CollectionOfElements
    @JoinTable(
        table=@Table(name="STUDENT_COURSE"),
        joinColumns=@JoinColumn(name="COURSE_ID")
    )
    private Set<JoinedStudentCourse> joined = new HashSet<JoinedStudentCourse>();

}

помните: у класса @Embeddable его жизненный цикл привязан к классу сущности-владельца (как ученика, так и курса), поэтому позаботьтесь об этом.

совет: команда Hibernate поддерживает эти два подхода (@OneToMany (ответ Скаффмана) или @CollectionsOfElements) из-за некоторых ограничений в @ManyToMany mapping - каскадная операция.

С уважением,

7 голосов
/ 20 июля 2009

Таблица student_course предназначена исключительно для записи связи между двумя сущностями. Он управляется Hibernate и не может содержать никаких других данных.

Вид данных, которые вы хотите записать, должен моделироваться как другой объект. Возможно, вы могли бы установить связь «один ко многим» между Course и StudentResult (которая содержит оценку и т. Д.), А затем ассоциацию «многие к одному» между StdentResult и Student.

3 голосов
/ 20 июля 2009

Отбросьте «многие ко многим», создайте класс с именем StudentCourseRelationship и установите один для manys в Student и Course для StudentCourseRelationship.

Вы можете помещать в него всевозможные вещи, такие как DateEnrolled, DateKickedOut и т. Д. И т. Д.

ИМО, сопоставление "многие ко многим" - нечто вроде "против".

2 голосов
/ 11 января 2013

Принятый ответ, к сожалению, не работает для меня, hibernate генерирует таблицу соединения странным образом (все столбцы соединения дублируются). Однако вариант с выделенной сущностью для таблицы соединений работает нормально. Здесь это описано очень подробно: http://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...