Spring Data JPA:在两个方向上保持多对多的关系

Spring Data JPA : persist a many to may relationship in both directions

我设法在子端保持多对多关系,(mappedBy),它工作得很好,如下所示:


学生实体(所有者)

package com.main.manytomany.models;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "students")
@Getter
@Setter
@NoArgsConstructor
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;


    @JsonIgnore
    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
    @JoinTable
            (
                    name = "students_courses",
                    joinColumns = {
                            @JoinColumn
                                    (
                                            name = "student_id",
                                            referencedColumnName = "id",
                                            nullable = false,
                                            updatable = false
                                    )
                    },
                    inverseJoinColumns = {
                            @JoinColumn
                                    (
                                            name = "course_id",
                                            referencedColumnName = "id",
                                            nullable = false,
                                            updatable = false
                                    )
                    }
            )
    private Set<Course> courses = new HashSet<>();


}

课程实体(儿童)

package com.main.manytomany.models;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "courses")
@Getter@Setter
@NoArgsConstructor
public class Course {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @ManyToMany(mappedBy = "courses", fetch = FetchType.LAZY)
    private Set<Student> students = new HashSet<>();
}

学生服务

package com.main.manytomany.services;

import com.main.manytomany.models.Student;
import com.main.manytomany.repositories.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class StudentService {

    private final StudentRepository studentRepository;

    @Autowired
    public StudentService(StudentRepository studentRepository) {
        this.studentRepository = studentRepository;
    }

    public List<Student> findAll() {
        return this.studentRepository.findAll();
    }

    public Student getOneById(Long id) {
        return this.studentRepository.getOne(id);
    }

    public void store(Student student) {

        this.studentRepository.save(student);
    }
}

课程服务

package com.main.manytomany.services;

import com.main.manytomany.models.Course;
import com.main.manytomany.models.Student;
import com.main.manytomany.repositories.CourseRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class CourseService {

    private final CourseRepository courseRepository;
    private final StudentService studentService;

    @Autowired
    public CourseService(CourseRepository courseRepository, StudentService studentService) {
        this.courseRepository = courseRepository;
        this.studentService = studentService;
    }

    public List<Course> findAll() {
        return this.courseRepository.findAll();
    }

    public void store(Course course) {

        course.getStudents()
                .addAll(course
                        .getStudents()
                        .stream()
                        .map(s -> {
                            Student student = studentService.getOneById(s.getId());
                            student.getCourses().add(course);
                            return student;
                        }).collect(Collectors.toList()));

        this.courseRepository.save(course);
    }
}

学生管理员 | Post映射

@PostMapping
public ResponseEntity<Void> create(@RequestBody Student student) {
    this.studentService.store(student);
    return new ResponseEntity<>(HttpStatus.CREATED);
}

课程管理员 | Post映射

@PostMapping
public ResponseEntity<Void> create(@RequestBody Course course) {
    this.courseService.store(course);
    return new ResponseEntity<>(HttpStatus.CREATED);
}

学生名单 | Post男人

课程列表 | Post男人

Students_Courses | Pivot Table + Hibernate 查询


如何让它在所有者中工作 table?

因此,与其在 CourseService 中持久化 运行ning,不如在 StudentService 中 运行、

因此,在 Postman 中,我将写一些类似的东西来指导学生,连同他的附加课程

{
    "name" : "John Doe",
    "courses" : [
        {
            "id" : 1
        },
                {
            "id" : 2
        }
        ]
}

您需要在 Course 实体中级联更改(与您在另一个方向上所做的方式几乎相同):

@ManyToMany(mappedBy = "courses", fetch = FetchType.LAZY, cascade = {
    CascadeType.PERSIST,
    CascadeType.MERGE
})
private Set<Student> students = new HashSet<>();

而不是使用 - mappedBy 这很好用(如果我们想保留一个实体作为父实体),您可以在两个表中使用 @JoinTable 并定义相应的方法来保存数据。

因此,更改下面的映射和 StudentService 中的 store 方法来保存课程是可行的。

@JsonIgnore
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinTable
        (
                name = "students_courses",
                joinColumns = {
                        @JoinColumn
                                (
                                        name = "course_id",
                                        referencedColumnName = "id",
                                        nullable = false,
                                        updatable = false
                                )
                },
                inverseJoinColumns = {
                        @JoinColumn
                                (
                                        name = "student_id",
                                        referencedColumnName = "id",
                                        nullable = false,
                                        updatable = false
                                )
                }
        )
private Set<Student> students = new HashSet<>();

示例:

@ManyToMany(fetch=FetchType.LAZY,cascade={CascadeType.PERSIST,CascadeType.DETACH,CascadeType.REFRESH,CascadeType.MERGE})
@JoinTable(name="course_student", joinColumns=@JoinColumn(name="course_id"), inverseJoinColumns=@JoinColumn(name="student_id"))
private List<Student> students;


@ManyToMany(fetch=FetchType.LAZY,cascade={CascadeType.PERSIST,CascadeType.DETACH,CascadeType.REFRESH,CascadeType.MERGE})
@JoinTable(name="course_student", joinColumns=@JoinColumn(name="student_id"), inverseJoinColumns=@JoinColumn(name="course_id"))
private List<Course> courses;