我正在使用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"
创建了两个不同的课程。
即使我已经创建了equals
和hashCode
方法实现。
需要解决方案,如何在Hibernate中处理这个问题。
答案 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认为这些是不同的。