Hibernate ManyToMany 多个条目
Hibernate ManyToMany Multiple Entries
我正在使用 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 中处理这个问题。
我认为您的问题来自 Course
class
中 equals()
方法的实施
确实,当您这样做时:
return this.courseName == anotherCourse.courseName;
,你比较this.courseName
的内存引用和anotherCourse
的courseName
。
相反,您应该使用 equals() 方法,如下所示:
return this.courseName.equals(anotherCourse.courseName);
,它比较字符串内容而不是引用。
在您的第二次尝试中,由于您创建了 2 个对象(具有相同的值),并且由于您在 Course
中实现 equals()
而是比较对象的引用(内存地址)关于它们的内容,Hibernate 认为它们是不同的。
我找到了以下问题的解决方案:
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
.
创建了一行条目
这样目的就解决了。
谢谢。
我正在使用 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 中处理这个问题。
我认为您的问题来自 Course
class
equals()
方法的实施
确实,当您这样做时:
return this.courseName == anotherCourse.courseName;
,你比较this.courseName
的内存引用和anotherCourse
的courseName
。
相反,您应该使用 equals() 方法,如下所示:
return this.courseName.equals(anotherCourse.courseName);
,它比较字符串内容而不是引用。
在您的第二次尝试中,由于您创建了 2 个对象(具有相同的值),并且由于您在 Course
中实现 equals()
而是比较对象的引用(内存地址)关于它们的内容,Hibernate 认为它们是不同的。
我找到了以下问题的解决方案:
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
.
这样目的就解决了。 谢谢。