Отношения один-ко-многим с MapStruct при весенней загрузке - PullRequest
0 голосов
/ 12 марта 2020

У меня есть все oop, когда я пытаюсь получить список студентов. Я использовал этот метод { ссылка }, и он работает, но только для одной специальности поля. Я попытался добавить еще одно поле факультета, но я получил ошибку stackoverflow. Как это решить?

Студент:

@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..
}

Факультет:

@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..
}

Специальность:

@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

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 :

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

SpecialtyDTO:

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:

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

Ответы [ 2 ]

0 голосов
/ 12 марта 2020

Я решил это с помощью @ aftermapping

Контроллер:

@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:

@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);
}
0 голосов
/ 12 марта 2020

Я думаю, что вы хотите удалить ссылки на факультеты и специальности

изменить:

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

        })

на:

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

         })
...