Hibernate ManyToMany多个条目

时间:2016-03-29 08:24:21

标签: java hibernate equality

我正在使用Hibernate 4.3 我为Student创建了以下实体。

@Entity
@Table(name="STUDENT")
public class Student {

    public Student(){
    }

    public Student(String name, Set<Course> courses){
        this.studentName = name;
        this.courses = courses;
    }

    @Id
    @GeneratedValue
    @Column(name="STUDENT_ID")
    private long studentid;
    @Column(name="STUDENT_NAME")
    private String studentName;
    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name="STUDENT_COURSE",
        joinColumns=@JoinColumn(name="STUDENT_ID"),
        inverseJoinColumns=@JoinColumn(name="COURSE_ID")
    )
    private Set<Course> courses = new HashSet<Course>(0);

    //Getter Setter Methods
}

另一个实体是Course

@Entity
@Table(name = "COURSE")
public class Course {

    public Course(String courseName) {
        this.courseName = courseName;
    }

    @Id
    @GeneratedValue
    @Column(name = "COURSE_ID")
    private long courseID;
    @Column(name = "COURSE_NAME")
    private String courseName;

    @ManyToMany(mappedBy="courses")
    private Set<Student> students = new HashSet<Student>(0);

    //Getter Setter Methods

    // I have added equality and hashcode check below

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof Course)) {
            return false;
        }
        Course anotherCourse = (Course) obj;
        // return this.courseName == anotherCourse.courseName;
        return (this.courseName == null)? anotherCourse.courseName == null : this.courseName.equals(anotherCourse.courseName);
    }

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

在我的应用程序中,我的代码为:

// Configuration and Session creation for Hibernate

Set<Course> courses = new HashSet<Course>();
courses.add(new Course("Maths"));
Student st1 = new Student("ABCD", courses);
session.save(st1);

courses.add(new Course("Physics"));
Student st2 = new Student("EFGH", courses);
session.save(st2);

在上述情况下,它会插入无效数据,作为两个学生的课程。 这是不正确的,但在Java中,对象是相同的,所以这是正确的。 但我希望课程按照上面的定义进行映射。如何在Hibernate端处理这个?

我尝试了另一个选项:

Set<Course> courses = new HashSet<Course>();
Set<Course> courses1 = new HashSet<Course>();
courses.add(new Course("Maths"));   
Student st1 = new Student("ABCD", courses);

session.save(st1);

courses1.add(new Course("Maths"));
courses1.add(new Course("Physics"));
Student st2 = new Student("EFGH", courses1);
session.save(st2);

但这次它为同一courseName = "Maths"创建了两个不同的课程。 即使我已经创建了equalshashCode方法实现。

需要解决方案,如何在Hibernate中处理这个问题。

2 个答案:

答案 0 :(得分:1)

我找到了问题的解决方案如下:

Course maths = new Course("Maths");
Course physics = new Course("Physics");

Set<Course> courses = new HashSet<Course>();
Set<Course> courses1 = new HashSet<Course>();

courses.add(maths);
Student st1 = new Student("ABCD", courses);
session.save(st1);

courses1.add(maths);
courses1.add(physics);
Student st2 = new Student("EFGH", courses1);
session.save(st2);

在这里,我为Course创建了对象,并在两个集合中使用了相同的对象。因此,在数据库中,它只为课程Maths创建了一个行条目。

从而解决了目的。 谢谢。

答案 1 :(得分:0)

我认为您的问题来自于equals()

Course方法的实施

确实,当你这样做时:

return this.courseName == anotherCourse.courseName;

,您将this.courseName的内存引用与courseName的{​​{1}}进行比较。

相反,您应该使用equals()方法,如下所示:

anotherCourse

,用于比较字符串内容而不是引用。

在第二次尝试中,由于您创建了2个对象(具有相同的值),并且因为return this.courseName.equals(anotherCourse.courseName); equals()的实现比较了对象的引用(内存地址)而不是它们的内容,Hibernate认为这些是不同的。