The app’s stack: Spring MVC
, Spring DataJPA
, Hibernate
. There are three entities: student
, tutor
, theme
.
Theme:
@Entity @Table(name = "themes") public class Theme { // fields omitted }
Student:
@Entity @Table(name = "students") public class Student { private Map<Theme, Tutor> tutors; // other fields omitted }
Tutor:
@Entity @Table(name = "tutors") public class Tutor { private Map<Theme, Student> students; // other fields omitted }
For save student-tutor-theme
relationships i want use this table (PostgreSQL):
CREATE TABLE themes_students_tutors ( theme_id INTEGER NOT NULL, student_id INTEGER NOT NULL, tutor_id INTEGER NOT NULL, FOREIGN KEY (theme_id) REFERENCES themes (id) ON DELETE CASCADE, FOREIGN KEY (student_id) REFERENCES students (id) ON DELETE CASCADE, FOREIGN KEY (tutor_id) REFERENCES tutors (id) ON DELETE CASCADE )
How i can to annotate tutors
and students
fields in entities, for their content correct persists in this table?
Advertisement
Answer
Like @kolossus mentioned: Use the @MapKeyJoinColumn
¹ annotation, so that the classes (or the map fields) look like this (you can ignore the extention of AbstractPersistable
):
Student:
public class Student extends AbstractPersistable<Long> { @ManyToMany @JoinTable(name = "themes_students_tutors", joinColumns = { @JoinColumn(name = "student_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "tutor_id", referencedColumnName = "id") }) @MapKeyJoinColumn(name = "theme_id") private Map<Theme, Tutor> tutors; }
Tutor:
public class Tutor extends AbstractPersistable<Long> { @ManyToMany @JoinTable(name = "themes_students_tutors", joinColumns = { @JoinColumn(name = "tutor_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "student_id", referencedColumnName = "id") }) @MapKeyJoinColumn(name = "theme_id") private Map<Theme, Student> students; }
Given that, something like this would be created:
Hibernate: create table students (id bigint not null, primary key (id)) Hibernate: create table themes (id bigint not null, primary key (id)) Hibernate: create table themes_students_tutors (tutor_id bigint not null, student_id bigint not null, theme_id bigint not null, primary key (student_id, theme_id)) Hibernate: create table tutors (id bigint not null, primary key (id)) Hibernate: alter table themes_students_tutors add constraint FKm5l4is34t5gs14p4skkv3aup7 foreign key (student_id) references students Hibernate: alter table themes_students_tutors add constraint FK8o0mm5ywi0l4hdxi4lgw4dbnu foreign key (theme_id) references themes Hibernate: alter table themes_students_tutors add constraint FKa0n6jvie0kmk0pmikcuvtepxh foreign key (tutor_id) references tutors
¹: See the Javadoc documentation of @MapKeyJoinColumn
for some other samples