多对多中的联合 table 未更新

Joint table in many-to-many is not updating

我在 2 个实体“Alumno”和“Curso”之间有关系 N:M:

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;
}

关于AlumnoService我有以下两种方法:

    @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);
    }

根据打印的行,所有数据都正确获取,并且在 Postman 上我得到了正确的答案:

{
    "id": 2,
    "name": "Marta",
    "dni": "67242062K",
    "age": 15,
    "cursos": [
        {
            "id": 3,
            "name": "Bootstrap 4",
            "length": 11,
            "alumnos": []
        }
    ]
}

这是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);
    }

然而,在检查数据库时,共享 table 是空的:

知道问题出在哪里吗?我忘了什么吗?我是 Spring boot 的新手。

感谢您的宝贵时间

此致

尝试使用 org.springframework.transaction.annotation 包中的 @Transactional 注释,看看它是否有效。

像这样:

@Transactional
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);
}

我发现问题出在实体的注释上。这是一个(据我所知)有效的解决方案:

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<>();


}

这里我添加了@JsonIgnore 以避免在显示列表时递归导致堆栈溢出。

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<>();
}

这里我给@ManyToMany 添加了mappedBy 属性。这就是它没有正确复制的原因。