简体   繁体   中英

Hibernate ManyToMany Multiple Entries

I am using Hibernate 4.3.
I have created below entity for 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
}

And another entity is 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();
    }
}

In my application I have code as:

// 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);

In the above case it inserts invalid data, as both courses for both the students. Which is incorrect, but as in Java the object is same so that is correct. But I want the courses to map as defined above. How to handle this at Hibernate end ?

I tried another option as:

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);

But this time it created two different courses for same courseName = "Maths" . Even if I have created a equals and hashCode method implementation.

Need solution, how to handle this in Hibernate.

I have found the solution for the issue as below:

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);

In this I have created objects for Course and used the same object in both set. So in the database it is created only one row entry for course Maths .

Thus solved the purpose. Thank you.

I believe your issue comes from the implementation of your equals() method in the Course class

Indeed, when you do this :

return this.courseName == anotherCourse.courseName;

, you compare the memory reference of this.courseName with the courseName of anotherCourse .

Instead, you should use the equals() method, like this :

return this.courseName.equals(anotherCourse.courseName);

, which compares the string content instead of the reference.

In your second attempt, since you create 2 objects (with the same value), and since your implementation of equals() in Course compares the reference (the memory address) of the objects instead of their content, Hibernate believes those are different.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM