0

I can't figure out how to map this exactly. I need the one to be String and the other one to be object, so I can't unfortunately make it easier for myself.

I have a RqgisterRequest class:

public class RegisterRequest {
    private String firstName;
    private String lastName;
    private String email;
    private String password;

    private Set<String> roles;

Here is my register method with Instance

 @PostMapping("/register")
    public HttpEntity authenticate(@Valid @RequestBody RegisterRequest registerRequest) {

        // create new user account
        User user = UserMapper.INSTANCE.registerRequestoUser(registerRequest);

        etc..

Here is my userDTO

@Data
@NoArgsConstructor
@AllArgsConstructor
public abstract class UserDTO extends BaseDTO {

    @JsonProperty("first_name")
    private String firstName;

    @JsonProperty("last_name")
    private String lastName;

    @JsonProperty("email")
    private String email;

    @JsonProperty("password")
    private String password;

    private Set<Role> roles;

    private Set<Appointment> appointments;

(my user entity is the same)

Here is my UserMapper class:

     User registerRequestoUser(RegisterRequest registerRequest);

And lastly the error I have when trying to run the program: Error:(20, 11) java: Can't map property "java.util.Set roles" to "java.util.Set roles". Consider to declare/implement a mapping method: "java.util.Set map(java.util.Set value)".

How should I tackle this problem?

jannis
  • 4,843
  • 1
  • 23
  • 53
mkashi
  • 59
  • 1
  • 7
  • does this help? https://stackoverflow.com/questions/34672216/cant-map-property-when-using-mapstruct – Majid Roustaei May 18 '20 at 08:31
  • THis depends on what youur Role class is. If you make it a simple enum, mapstruct should be able to map it, if it is more complex, write a custom mapper method – Amir Schnell May 18 '20 at 08:31

2 Answers2

0

Since MapStuct don't know how to map a String to Role, you have to explicite define the mapping role. Change the interface to an abstract mapper class, then you can implement specific mapping to the given property.

@Mappings(value={ @Mapping(source="roles", target="roles", qualifiedByName="customRoleMapper")}
abstract User registerRequestoUser(RegisterRequest registerRequest);

Then implement the mapper:

@Named(value = "customRoleMapper")
public List<Role> customRoleMapper(List<String> roles){
   //create a new role list where you instantiate a Role from every string  and put it into the new list, then return with the new list
}
zlaval
  • 1,941
  • 1
  • 10
  • 11
0

The easiest way to do this is to provide a mapping method from String into Role.

e.g.

default Role toRole(String role) {
    return role != null ? new Role( role ) : null;
}

You can put this in your mapper or in a util class and MapStruct will be able to use it for the mapping.

Filip
  • 19,269
  • 7
  • 51
  • 60