Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do bidirectional entities require both sides to add each other in Hibernate?

Tags:

java

hibernate

Do bidirectional entities (OneToMany, ManyToMany) require both sides to add each other to be saved correctly in Hibernate? From my experience, they are required. Just trying to confirm my understanding.

That is, for the entitles below, are the indicated lines required?

        Student student = new Student("Carl");
        Course course = new Course("Science");
        ReportCard reportCard = new ReportCard("A");

        student.getCourses().add(course);
        student.getReportCards().add(reportCard);

        reportCard.setStudent(student); // <-- Is this required?
        course.getStudents().add(student); // <-- Is this required?

        studentRepository.save(student);

Student.java

@Entity
public class Student { 
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "student")
    private List<ReportCard> reportCards = new ArrayList<ReportCard>();

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(joinColumns = @JoinColumn(name = "student_id"), inverseJoinColumns = @JoinColumn(name = "course_id"))
    private List<Course> courses = new ArrayList<Course>();

    @Column
    private String name;

}

ReportCard.java

@Entity
public class ReportCard {
    @ManyToOne(optional = false)
    @JoinColumn(nullable = false)
    private Student student;

    @Column
    private String grade;
}

Course.java

@Entity
public class Course {
    @ManyToMany(mappedBy = "courses")
    public List<Student> students = new ArrayList<>();

    @Column
    private String name;
}

EDIT: Replaced @JoinColumn with @Column

like image 570
Glide Avatar asked Sep 06 '25 07:09

Glide


1 Answers

Hibernate (ad other JPA implementations) cares about the owning side of the association. The owning side is the side which doesn't have the mappedBy attribute. So, in your example, reportCard.setStudent(student);is required, but student.getReportCards().add(reportCard); is not.

But in general, it's indeed best to set each side of the association correctly, to have a coherent graph of objects and simply avoid bugs in your code.

Note that annotating your String fields with JoinColumn is wrong. They're not join columns, but columns. So you should annotate them with @Column, although it's also useless if you don't specify any attribute of the annotation.

like image 184
JB Nizet Avatar answered Sep 09 '25 02:09

JB Nizet