简体   繁体   English

Spring Boot 中与 MapStruct 的一对多关系

[英]One to Many relationship with MapStruct in spring boot

I have a loop when I try to get a list of students.当我尝试获取学生列表时,我有一个循环。 I used this method https://stackoverflow.com/a/57311104/12350684 and it works, but only for one field specialty.我使用了这种方法https://stackoverflow.com/a/57311104/12350684并且它有效,但仅适用于一个领域专业。 I tried to add another field faculty, but I got stackoverflow error.我试图添加另一个现场教师,但我遇到了计算器溢出错误。 How to solve this?如何解决这个问题?

Student:学生:

@Entity
@Table(name="student")
public class Student  {

    @Id
    @Column(name="numberzachetka", nullable = false)
    private long numberzachetka;

    @Column(name="fiostudent", nullable = false, length = 100)
    private String fio;

    @Temporal(TemporalType.DATE)
    @Column(name = "entrydate", nullable = false)
    private Date entrydate;

    @Column(name="course", nullable = false)
    private int course;

    @Column(name="numbergroup", nullable = false)
    private int numbergroup;

    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "specialtykey", nullable = false)
    private Specialty specialty;

    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "facultynumber", nullable = false)
    private Faculty faculty;
//getters, setters..
}

Faculty:学院:

@Entity
@Table(name="faculty")
public class Faculty {
    @Id
    @Column(name="facultynumber",nullable = false)
    private long number;

    @Column(name="facultyname",nullable = false, length = 50)
    private String name;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "faculty")
    private Set<Student> students;
//getters,setters..
}

Specialty:专业:

@Entity
@Table(name="specialty")
public class Specialty {

    @Id
    @Column(name="specialtykey",nullable = false)
    private long key;

    @Column(name="specialtyname",nullable = false, length = 100)
    private String name;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "specialty")
    private Set<Student> students;
//...
}

StudentDTO学生DTO

public class StudentDTO {
    private long numberzachetka;
    private String fio;
    private Date entrydate;
    private int course;
    private int numbergroup;
    private SpecialtyDTO specialty;
    private FacultyDTO faculty;

FacultyDTO: FacultyDTO:

public class FacultyDTO {
    private long number;
    private String name;
    private Set<StudentDTO> students;

SpecialtyDTO:专业DTO:

public class SpecialtyDTO {
    private long key;
    private String name;
    private Set<StudentDTO> students;

SpecialtyMapper:专业映射器:

@Mapper(uses = StudentMapper.class)
public interface SpecialtyMapper {

    @Mapping(target = "students", source = "students", qualifiedByName = "studentDTOList")
    SpecialtyDTO toDTO(Specialty specialty);
}

FacultyMapper: FacultyMapper:

@Mapper(uses = StudentMapper.class)
public interface FacultyMapper {

    @Mapping(target = "students", source = "students", qualifiedByName = "studentDTOList")
    FacultyDTO toDTO(Faculty faculty);
}

StudentMapper:学生映射器:

@Mapper(uses = {FacultyMapper.class, SpecialtyMapper.class})
public interface StudentMapper {

    @Mapping(target = "faculty.students", ignore = true)
    @Mapping(target = "specialty.students", ignore = true)
    StudentDTO toDTO(Student entity);


    @Named("studentDTOList")
    default List<StudentDTO> toStudentDTOList(List<Student> source) {
        return source
                .stream()
                .map(this::toDTO)
                .peek(dto -> {
                                dto.setFaculty(dto.getFaculty());
                                dto.setSpecialty(dto.getSpecialty());

                })
                .collect(Collectors.toList());
    }
}

I think you want to remove faculty and speciality references我认为您想删除教师和专业参考

change:改变:

       .peek(dto -> {
                        dto.setFaculty(dto.getFaculty());
                        dto.setSpecialty(dto.getSpecialty());

        })

to:到:

        .peek(dto -> {
                                dto.setFaculty(null);
                                dto.setSpecialty(null);

         })

I solved this with help of @aftermapping我在@aftermapping 的帮助下解决了这个问题

Controller:控制器:

@GetMapping("")
    public List<StudentDTO> findAll() {
        List<Student> students = studentService.findAll();
        List<StudentDTO> studentDTOS = new ArrayList<>();

        for(Student el : students){
            StudentDTO std =StudentMapper.INSTANCE.toDTO(el);
            System.out.println(std.getFaculty()+" "+std.getSpecialty());
            studentDTOS.add(std);
        }
        return studentDTOS;
    }

StudentMapper:学生映射器:

@Mapper(uses = {FacultyMapper.class, SpecialtyMapper.class})
public interface StudentMapper {

    StudentMapper INSTANCE = Mappers.getMapper(StudentMapper.class);

    @Mapping(target = "faculty", ignore = true)
    @Mapping(target = "specialty", ignore = true)
    StudentDTO toDTO(Student entity);

    @AfterMapping
    default void setStudentSpecialtyFaculty(@MappingTarget StudentDTO studentDTO, Student student) {
        FacultyDTO f = FacultyMapper.INSTANCE.toDTO(student.getFaculty());
        SpecialtyDTO s = SpecialtyMapper.INSTANCE.toDTO(student.getSpecialty());

        studentDTO.setFaculty(f);
        studentDTO.setSpecialty(s);
    }
}

FacultyMapper: FacultyMapper:

@Mapper(uses = StudentMapper.class)
public interface FacultyMapper {

    FacultyMapper INSTANCE = Mappers.getMapper(FacultyMapper.class);

    @Mapping(target = "students", ignore = true)
    FacultyDTO toDTO(Faculty faculty);
}

SpecialtyMapper:专业映射器:

@Mapper(uses = StudentMapper.class)
public interface SpecialtyMapper {

    SpecialtyMapper INSTANCE = Mappers.getMapper(SpecialtyMapper.class);

    @Mapping(target = "students", ignore = true)
    SpecialtyDTO toDTO(Specialty specialty);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM