Student单向ManyToMany Course, 中间表是Score, 其中Score单向ManyToMany Student和Course,Score中用studentId和courseId作为联合主键,同时还有自己的字段score成绩(nullable=true)。在保存时:new 一个Student、Course、Score, 设置好关系后,Score.setScore(90) 设置成绩分数,结果执行两次insert into score,duplicate entry for primary key.
@Entity
@Table(name="t_student")
public class Student { private int id;
private String name;
private Set<Course> courses = new HashSet<Course>();
@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToMany
@JoinTable(name="t_score",joinColumns={@JoinColumn(name="studentId")},inverseJoinColumns={@JoinColumn(name="courseId")})
public Set<Course> getCourses() {
return courses;
}
public void setCourses(Set<Course> courses) {
this.courses = courses;
}

}@Entity
@Table(name="t_course")
public class Course { private int id;
private String name;
@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Entity
@Table(name="t_score")
@IdClass(ScorePK.class)
public class Score {
private int score;
private Student student;
private Course course;
@Column(nullable=true)
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Id
@ManyToOne
@JoinColumn(name="studentId")
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
@Id
@ManyToOne
@JoinColumn(name="courseId")
public Course getCourse() {
return course;
}
public void setCourse(Course course) {
this.course = course;
}

}
@Entity
public class ScorePK implements java.io.Serializable{
private Student student;
private Course course;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public Course getCourse() {
return course;
}
public void setCourse(Course course) {
this.course = course;
}

@Override
public boolean equals(Object o){
if(o instanceof ScorePK){
ScorePK t = (ScorePK) o;
return t.getStudent() == this.getStudent()
&& t.getCourse()==this.getCourse();
}
return false;
}

@Override
public int hashCode(){
return this.student.hashCode();
}
}

解决方案 »

  1.   

    [code]
    session.beginTransaction();
    Course c = new Course();
    c.setId(21);
    c.setName("English");

    Student s = new Student();
    s.setId(11);
    s.setName("Hiway");
    s.getCourses().add(c);

    Score sc = new Score();
    sc.setScore(90);
    sc.setStudent(s);
    sc.setCourse(c);

    session.save(c);
    session.save(s);
    session.save(sc);

    session.getTransaction().commit();
    [/code]
    显示的sql中:
    执行两次insert into t_score
    Hibernate: 
        insert 
        into
            t_score
            (score, courseId, studentId) 
        values
            (?, ?, ?)
    Hibernate: 
        insert 
        into
            t_score
            (studentId, courseId) 
        values
            (?, ?)
    显然是有问题的。
    如果session.save(sc) 注释掉的话,则只执行一次insert into score,但那个分数没插进去。请问如何解决?
      

  2.   

    [code]
    session.beginTransaction();
    Course c = new Course();
    c.setId(21);
    c.setName("English");

    Student s = new Student();
    s.setId(11);
    s.setName("Hiway");
    s.getCourses().add(c);

    Score sc = new Score();
    sc.setScore(90);
    sc.setStudent(s);
    sc.setCourse(c);

    session.save(c);
    session.save(s);
    session.save(sc);

    session.getTransaction().commit();
    [/code]这是测试代码
      

  3.   


    session.beginTransaction();
    Course c = new Course();
    c.setId(21);
    c.setName("English");

    Student s = new Student();
    s.setId(11);
    s.setName("Hiway");
    s.getCourses().add(c);

    Score sc = new Score();
    sc.setScore(90);
    sc.setStudent(s);
    sc.setCourse(c);

    session.save(c);
    session.save(s);
    session.save(sc);

    session.getTransaction().commit();