Mapstruct позволяет избежать круговой проблемы со свойством List <A>в классе B - PullRequest
0 голосов
/ 03 февраля 2020

Если у меня есть класс ProfessorDto и класс StudentDto , как можно избежать циклических проблем, если ProfessorDto имеет список StudentDto, а StudentDto имеет свойство типа ProfessorDto? Я не поместил код класса домена, но допустим, что он такой же, как и для Dto.

Я новичок в Mapstruct, преобразовываю бин домена в Dto с простыми свойствами, такими как Long, String работает, но в моем примере связь OneToMany не работает!

@JsonApiResource(type = "professor")
@NoArgsConstructor
@Data
public class ProfessorDto {

  @JsonApiId
  private Long id;

  private String professorName;

  @JsonApiRelation(mappedBy = "professor")
  private List<StudentDto> student;

  public ProfessorDto(Long id) {
    this.id = id;
  }
}

И ученик класса

@JsonApiResource(type = "student")
@NoArgsConstructor
@Data
public class StudentDto {

  @JsonApiId
  private Long id;

  private String studentName;

  @JsonApiRelation
  private ProfessorDto professor;
}

Мой картограф для профессора

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface ProfessorMapper {

  ProfessorDto domainToDto(Professor domain);

  Professor dtoToDomain(ProfessorDto dto);

  StudentDto studentToDto(Student student);

  Student studentDtoToDomain(StudentDto studentDto);

  List<StudentDto> studentToDto(List<Student> student);

  List<Student> studentDtoToDomain(List<StudentDto> studentDto);
}

Ответы [ 2 ]

0 голосов
/ 03 февраля 2020

Сначала вы должны решить, действительно ли нужно сохранять List<StudentDto> агрегированным в ProfessorDto. Вы можете просто исключить это, если это возможно.
В противном случае вы можете сделать StudentDto или ProfessorDto «плоским». Например, вы можете добавить поле Long professorId вместо ProfessorDto professor к StudentDto или List<Long> studentIds к ProfessorDto.

Пример подхода с использованием Mapstruct:

  1. Измените класс DTO следующим образом:

    @JsonApiResource(type = "student")
    @NoArgsConstructor
    @Data
    public class StudentDto {
    
        @JsonApiId
        private Long id;
    
        private String studentName;
    
        private Long professorId; // <-- CHANGED 
    }
    
  2. Добавьте вспомогательный класс и предоставьте пользовательские логи отображения c:

    @Component
    public class MapperHelper {
        @AfterMapping
        public void mapProfessorId(Student student, @MappingTarget StudentDto studentDto) {
            studentDto.setProfessorId(student.getProfessor().getId());
        }
    }
    
0 голосов
/ 03 февраля 2020

посмотрите этот пример, используя аннотацию @Context

https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-mapping-with-cycles/src/main/java/org/mapstruct/example/mapper

Подробнее о аннотации @Context можно найти в документации Mapstruct ниже

https://mapstruct.org/documentation/stable/api/org/mapstruct/Context.html

...