I have a relation N:M between 2 entities, “Alumno” and “Curso”:
Alumno
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "alumno")
public class Alumno {
@Id
@GeneratedValue
private int id;
private String name;
private String dni;
private int age;
@ManyToMany(mappedBy = "alumnos", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<Curso> cursos;
}
Curso
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "curso")
public class Curso {
@Id
@GeneratedValue
private int id;
private String name;
private int length;
@ManyToMany
private List<Alumno> alumnos;
}
On AlumnoService I have the following two methods:
@Autowired
private AlumnoRepository repository;
@Autowired
private CursoService cursoService;
...
//Non-related stuff
...
public Alumno updateAlumno(Alumno alumno) {
Alumno existingAlumno = repository.findById(alumno.getId()).orElse(null);
existingAlumno.setName(alumno.getName());
existingAlumno.setDni(alumno.getDni());
existingAlumno.setAge(alumno.getAge());
return repository.save(existingAlumno);
}
public Alumno insertCurso(int id_alumno, int id_curso) {
Alumno alumno = repository.findById(id_alumno).orElse(null);
System.out.println("Found alumno: => " + alumno.getId() + " " + alumno.getName());
Curso curso = cursoService.getCursoById(id_curso);
System.out.println("Found curso: => " + curso.getId() + " " + curso.getName());
alumno.getCursos().add(curso);
System.out.println("========");
for (Curso c: alumno.getCursos()) {
System.out.println(c.getId() + " " + c.getName());
}
System.out.println("==========");
return updateAlumno(alumno);
}
According to the printed lines, all the data is fetch correctly, and on Postman I get a correct answer:
{
"id": 2,
"name": "Marta",
"dni": "67242062K",
"age": 15,
"cursos": [
{
"id": 3,
"name": "Bootstrap 4",
"length": 11,
"alumnos": []
}
]
}
This is the AlumnoController:
@Autowired
private AlumnoService service;
@PutMapping("/insertCurso/{id_a}/{id_c}")
public Alumno insertCurso(@PathVariable("id_a") int id_a, @PathVariable("id_c") int id_c) {
return service.insertCurso(id_a, id_c);
}
However, upon inspecting the database, the shared table is empty:

Any idea on what the issue might be? Did I forget something? I’m completely new to Spring boot.
Thank you for your time
Best regards
Advertisement
Answer
I found the problem was on the annotations of the entities. Here is a solution that (as far as I know) works:
Alumno
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "alumno")
public class Alumno {
@Id
@GeneratedValue
private int id;
private String name;
private String dni;
private int age;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "matriculas",
joinColumns = @JoinColumn(name = "alumno_id"),
inverseJoinColumns = @JoinColumn(name = "curso_id")
)
@JsonIgnore
private List<Curso> cursos = new ArrayList<>();
}
Here I added the @JsonIgnore to avoid recursion leading to a stack overflow while displaying the lists.
Curso
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "curso")
public class Curso {
@Id
@GeneratedValue
private int id;
private String name;
private int length;
@ManyToMany(cascade = CascadeType.ALL, mappedBy = "cursos")
private List<Alumno> alumnos = new ArrayList<>();
}
Here I added the mappedBy attribute to the @ManyToMany. This was the reason it wasn’t replicating correctly.