我有这两个类(表)
@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表)) 我看到一些解决方案,但我不喜欢它们,我也有一些问题:
答案 0 :(得分:16)
如果您在链接表(STUDENT_COURSE)上添加额外字段,则必须根据skaffman的答案选择一种方法,如下图所示。
有一种方法,链接表(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(skaffman的答案)或@CollectionsOfElements),因为@ManyToMany映射中的一些限制 - 级联操作。
的问候,
答案 1 :(得分:7)
student_course表纯粹是为了记录两个实体之间的关联。它由hibernate管理,不能包含其他数据。
您要记录的数据类型需要建模为另一个实体。也许你可以在Course和StudentResult(包含成绩等)之间进行一对多的关联,然后在StdentResult和Student之间进行多对一的关联。
答案 2 :(得分:3)
删除多对多,创建一个名为StudentCourseRelationship的课程,并在StudentTourseRelationship上为学生和课程设置一个。
您可以在其上添加各种内容,例如DateEnrolled,DateKickedOut等。
IMO多对多映射有点像。
答案 3 :(得分:2)
遗憾的是,接受的答案对我不起作用,hibernate以一种奇怪的方式生成连接表(所有连接列都是重复的)。但是,具有连接表的专用实体的变体可以正常工作。这里详细介绍了它:http://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/