Suppose you have a Student and Subject entities and you want to create a many-to-many relationship between them. The database table looks something like this:
CREATE TABLE students ( `id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, `name` VARCHAR(200) ); CREATE TABLE subjects ( `id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, `name` VARCHAR(200) ); CREATE TABLE students_subjects ( `student_id` BIGINT NOT NULL, `subject_id` BIGINT NOT NULL, PRIMARY KEY (`student_id`, `subject_id`), FOREIGN KEY (`student_id`) REFERENCES `students` (`id`), FOREIGN KEY (`subject_id`) REFERENCES `subjects` (`id`) );
Here’s how to code your Student JPA entity:
(name = "students") public class Student { @Id private long id; private String name = ""; (cascade = CascadeType.All) (name = "students_subjects", joinColumns = (name = "student_id", referencedColumnName = "id"), inverseJoinColumns = (name = "subject_id", referencedColumnName = "id")) private Setsubjects = new HashSet (); /* getters, setters, equals & hashCode */ }
Note how I used CascadeType.All above, this will case any modification to subjects collections to be cascaded automatically when I saved the student entity object.
Also note the use of Set collection instead of List. This will prevent duplicates when querying since JPA wouldn’t know whether the multiple rows are a result of join or simply multiple entries in the result.
And here’s the Subject JPA entity:
(name = "subjects") public class Subject { @Id private long id; private String name = ""; (cascade = CascadeType.All) (name = "students_subjects", joinColumns = (name = "subject_id", referencedColumnName = "id"), inverseJoinColumns = (name = "student_id", referencedColumnName = "id")) private Setstudents = new HashSet (); /* getters, setters, equals & hashCode */ }
Note that the annotation on Subject is similar to Student except the joinColumns and inverseJoinColumns are reversed.
Also since the above example uses HashSet, don’t forget to implement proper equals and hashCode methods.