ManyToMany
Vamos aqui a um exemplo clássico (bem parecido com o que estamos fazendo).
Imagine um sistema de gerenciamento de cursos e alunos. Um aluno pode se inscrever em vários cursos e um curso pode ter vários alunos. Portanto, há uma relação Many-to-Many entre "Alunos" e "Cursos".
Nenhuma das tabelas pode ter uma coluna que referencie diretamente a outra sem criar muita redundância, pois um aluno pode estar associado a múltiplos cursos, e o curso a múltiplos alunos.
Para implementar essa relação em um banco de dados relacional, geralmente se cria uma tabela intermediária (ou tabela de junção), que mapeia a associação entre as duas tabelas principais. No exemplo acima, teríamos:
Entidade Aluno
Entidade Curso
E faríamos o mapeamento para criar a tabela intermediária
Aluno
@Entity
public class Aluno {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nome;
@ManyToMany
@JoinTable(
name = "aluno_curso", // Nome da tabela intermediária
joinColumns = @JoinColumn(name = "aluno_id"), // Chave estrangeira de Aluno
inverseJoinColumns = @JoinColumn(name = "curso_id") // Chave estrangeira de Curso
)
private Set<Curso> cursos = new HashSet<>();
// Construtores, getters e settersCurso
@Entity
public class Curso {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nome;
@ManyToMany(mappedBy = "cursos") // Relacionamento inverso
private Set<Aluno> alunos = new HashSet<>();
// Construtores, getters e settersAtualizado