1

I have a bidirectional mapping in Spring Boot:

Company.class

...
private Integer id;
private String nameC;
@OneToMany
private List<Employee> employees;
...

Employee.class

...
private Integer id;
private String nameE;
@ManyToOne
private Company company;
...

Now I want to make mapping with map struct to these DTOs

CompanyDTO

private Integer id;
private String nameC;
private List<EmployeeDTO> employees;

EmployeeDTO

private Integer id;
private String nameE;
private Integer company; // so this should be Company ID

MapCompany

Company toCompany(CompanyDTO cDto)

CompanyDTO toCompanyDTO(Company c)

MapEmployee

Employee toEmployee(EmployeeDTO eDto)

EmployeeDTO toEmployeeDTO(Employee emp)

@Mapping(target = "company.id", source = "eDto.company")
List<Employee> toEmployee(List<EmployeeDTO> eDto)

@Mapping(target = "company", source = "emp.company.id")
List<EmployeeDTO> toEmployeeDTO(List<Employee> emp)

Now,

  1. First of all I can't get mapping for toEmployee and toEmployeeDTO, the error says "The type of parameter "eDto" has no property named "company"" and " The type of parameter "emp" has no property named "emp.company.id"" I suppose that this is because eDto and emp are List<>. So how can I get the "company" parameter from List<> in MapStruct?
  2. Later, even if I remove those mappings with lists, there is a problem because it is bidirectional relation and I can't get the CompanyId in EmployeeDTO. The error is " Ambiguous mapping methods found for mapping property "Company company" " Is there a way to do this in MapStruct or I have to use my custom mappers?
Ewe
  • 125
  • 9
  • I don't know if this is a typing error in the question or in the code, so I will point it out anyway. You have company in your entity, but you are trying to access compnay. Check the spelling – James Wagstaff Oct 04 '22 at 14:13
  • It was a mistake, I changed it. – Ewe Oct 04 '22 at 14:19

1 Answers1

2

Try this

@Named("toEmployee")
Employee toEmployee(EmployeeDTO eDto)

@Named("toEmployeeDTO")
EmployeeDTO toEmployeeDTO(Employee emp)

@IterableMapping(qualifiedByName = "toEmployee")
List<Employee> toEmployee(List<EmployeeDTO> eDto)

@IterableMapping(qualifiedByName = "toEmployeeDTO")
List<EmployeeDTO> toEmployeeDTO(List<Employee> emp)
Shivaji Pote
  • 479
  • 4
  • 6
  • 1
    This resolve the problem with List<>. but not for "Ambiguous mapping..." in CompnyMapper. Any way I tried to use ignore=true for Employee fields in CompanyMapper and using @AfterMapping to fill them again. This solved my problem but I'm not sure if this is right approach, if you have any suggestion on this it would be great. Thank you – Ewe Oct 04 '22 at 14:33
  • 1
    Use @Mapping on top of Employee/EmployeeDTO mappers like this: `@Named("toEmployee") @Mapping(target = "id", source = "eDto.id") Employee toEmployee(EmployeeDTO eDto) @Named("toEmployeeDTO") @Mapping(target = "id", source = "emp.id") EmployeeDTO toEmployeeDTO(Employee emp)` If this doesn't work, please share minimum reproducible example. I will take a look. – Shivaji Pote Oct 06 '22 at 07:55
  • 1
    Yes, if I put `@Mapping` and `@Named` on all methods in EmployeeMapper, it works, but I didn't know why. Actually after that I found what problem was: Besides these mappers I have one more (EmployeeDTOInput for which I also had a mapping methods) and EmployeeDTO extends from this class (I didn't put this in code because I thought this is not an issue), and that was the problem where "Ambiguous mapping methods found..." arrived. So I remove the extends and put everything in one Class and everything was OK. Thank you for your answer. – Ewe Oct 07 '22 at 07:14