I have these two class(table)
@Entity
@Table(name = \"course\")
public class Course {
@Id
@Column(name = \"courseid\")
private String courseId;
The student_course table is there purely to record the association between the two entities. It is managed by hibernate, and can contain no other data.
The sort of data you want to record needs to be modelled as another entity. Perhaps you could a one-to-many association between Course and StudentResult (which contains the grade, etc), and then a many-to-one association between StdentResult and Student.
The accepted answer unfortunately doesn't work for me, hibernate generates the join table in a weird way (all join columns are duplicated). However the variant with dedicated entity for the join table works fine. Here it is described in great detail: http://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/
If you add extra fields on a linked table (STUDENT_COURSE), you have to choose an approach according to skaffman's answer or another as shown bellow.
There is an approach where the linked table (STUDENT_COURSE) behaves like a @Embeddable according to:
@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
}
}
So you will have in both Student and Course classes
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>();
}
remember: @Embeddable class has its lifecycle bound to the owning entity class (Both Student and Course), so take care of it.
advice: Hibernate team suppports these two approachs (@OneToMany (skaffman's answer) or @CollectionsOfElements) due some limitations in @ManyToMany mapping - cascade operation.
regards,
Drop the many-to-many, create a class called StudentCourseRelationship and set up one to manys on Student and Course to the StudentCourseRelationship.
You can put all sorts of things on it, like DateEnrolled, DateKickedOut etc. etc.
IMO the many-to-many mapping is a bit of a con.