Unidirectional many-to-many mapping

Many-to-many relationships are a bit more complex than one-to-many or many-to-one relationships, as they involve an intermediate table to represent the relationship between the two entities. Here are examples of unidirectional and bidirectional many-to-many mappings, along with descriptions of the annotations used:

In this example, we have two entities: Course and Student. A Course can have many Students, and a Student can be enrolled in many Courses.

        
    @Entity
    @Table(name = "courses")
    public class Course {
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Long id;

      @Column(name = "name")
      private String name;

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

      // getters and setters
    }
        
      
        
    @Entity
    @Table(name = "students")
    public class Student {
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Long id;

      @Column(name = "name")
      private String name;

      // getters and setters
    }
        
      

In the Course entity, we have:

@ManyToMany(cascade = CascadeType.ALL):

Specifies that many Course instances can be associated with many Student instances. The cascade = CascadeType.ALL attribute specifies that any changes made to a Course instance should be propagated to all associated Student instances.

@JoinTable:

Specifies the name of the intermediate table that should be used to store the relationship between Course and Student instances. The name attribute specifies the name of the table, and the joinColumns and inverseJoinColumns attributes specify the foreign key columns that should be used to link Course and Student instances together.

In the Student entity, we have:

* No mention of the Course entity, because this is a unidirectional mapping.

Here's an example of how to create and persist Course and Student instances:

        
      Course course = new Course();
      course.setName("Java Programming");

      Student student1 = new Student();
      student1.setName("John");

      Student student2 = new Student();
      student2.setName("Jane");

      course.getStudents().add(student1);
      course.getStudents().add(student2);

      session.save(course);
        
      

In this example, we create a new Course instance and set its name to "Java Programming". We also create two new Student instances and set their names. Finally, we add both Student instances to the Course instance's students list and save the Course instance to the database using the Hibernate Session object.

Bidirectional many-to-many mapping

In this example, we modify the previous example to add a bidirectional mapping between Course and Student.

        
    @Entity
    @Table(name = "courses")
    public class Course {
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Long id;

      @Column(name = "name")
      private String name;

      @ManyToMany(cascade = CascadeType.ALL, mappedBy = "courses")
      private List<Student> students = new ArrayList<>();

        // getters and setters
    }
        
      
        
    @Entity
    @Table(name = "students")
    public class Student {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;

        @Column(name = "name")
        private String name;

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

          // getters and setters
    }

      

In the Course entity, we have:

@ManyToMany(cascade = CascadeType.ALL, mappedBy = "courses"):

This annotation specifies that a many-to-many relationship exists between Course and Student entities. The cascade = CascadeType.ALL attribute specifies that all operations on a Course entity (including persisting, updating, and deleting) should be propagated to associated Student entities. The mappedBy attribute specifies that the relationship is bidirectional, and that the inverse side of the relationship is managed by the courses attribute of the Student entity.

In the Student entity, we have:

@ManyToMany(cascade = CascadeType.ALL):

This annotation specifies that a many-to-many relationship exists between Student and Course entities. The cascade = CascadeType.ALL attribute specifies that all operations on a Student entity (including persisting, updating, and deleting) should be propagated to associated Course entities.

@JoinTable:

This annotation specifies the name of the intermediate table that should be used to store the relationship between Student and Course entities. The name attribute specifies the name of the table, and the joinColumns and inverseJoinColumns attributes specify the foreign key columns that should be used to link Student and Course entities together.

Here's an example of how to create and persist Course and Student instances using the bidirectional many-to-many mapping:

        
          Course course = new Course();
          course.setName("Java Programming");

          Student student1 = new Student();
          student1.setName("John");

          Student student2 = new Student();
          student2.setName("Jane");

          course.getStudents().add(student1);
          course.getStudents().add(student2);

          student1.getCourses().add(course);
          student2.getCourses().add(course);

          session.save(course);

      

In this example, we create a new Course instance and set its name to "Java Programming". We also create two new Student instances and set their names. Finally, we add the Student instances to the Course instance's students list, and add the Course instance to each Student instance's courses list. Then, we save the Course instance to the database using the Hibernate Session object.