Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
209 views
in Technique[技术] by (71.8m points)

java - Use MapStruct to convert member variable to id (and vice versa)

In my SpringBoot application, I have two entities User and Role with

public class User {
    private Long id;
    private String email;
    private String password;
    private Set<Role> roles;

    [...]
}

public class Role {
    private Long id;
    private String name;
    private Set<User> users;

    [...]
}

My DTOs looked quite similar until I realized this could lead to a recursion problem, when a user has a field role which has a field of the same user, which has a field of the same role, etc.

Therefore I decided to hand only the ids my DTOs, so they would look like this

public class UserDto {

    private Long id;
    private String email;
    private String password;
    private List<Long> roleIds;
}

public class RoleDto {
    private Long id;
    private String name;
    private List<Long> userIds;
}

My mappers were quite simple and used to look like this

import org.mapstruct.Mapper;
@Mapper
public interface UserMapper {
    User userDtoToUser(UserDto userDto);
    UserDto userToUserDto(User user);
    List<UserDto> userListToUserDtoList(List<User> users);
}


import org.mapstruct.Mapper;
@Mapper
public interface RoleMapper {
    Role roleDtoToRole(RoleDto roleDto);
    RoleDto roleToRoleDto(Role Role);
    List<RoleDto> roleListToRoleDtoList(List<Role> roles);
}

How would I change them so they would convert users to/from userIds and roles to/from roleIds?

question from:https://stackoverflow.com/questions/65829746/use-mapstruct-to-convert-member-variable-to-id-and-vice-versa

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The unidirectional mapping from roles to rolesDtos or users to usersDtos is quite simple

@Mapper
public interface RoleMapper {

    List<RoleDto> roleListToRoleDtoList(List<Role> role);

    @Mapping(target = "userIds", source = "users", qualifiedByName = "userListToUserDtoList")
    RoleDto roleToRoleDto(Role role);

    @Named("userListToUserDtoList")
    default List<Long> userListToUserDtoList(Set<User> users) {
        return users.stream().map(User::getId).collect(Collectors.toList());
    }
}

@Mapper
public interface UserMapper {

    List<UserDto> userListToUserDtoList(List<User> users);

    @Mapping(target = "roleIds", source = "roles", qualifiedByName = "roleListToRoleDtoList")
    UserDto userToUserDto(User user);

    @Named("roleListToRoleDtoList")
    default List<Long> roleListToRoleDtoList(Set<Role> roles) {
        return roles.stream().map(Role::getId).collect(Collectors.toList());
    }
}

The real problem is to map

User userDtoToUser(UserDto userDto);

or

Role roleDtoToRole(RoleDto roleDto);

Because here MapStruct doesn't know how to convert userIds to users you need some mechanism to fetch each userId and parse it to the whole object. If you are using Spring you can make your mappers as Spring beans - https://mapstruct.org/documentation/stable/reference/html/#using-dependency-injection or decorators https://mapstruct.org/documentation/stable/reference/html/#decorators-with-spring for a "fetching method" injecting somehow proper repository.
, but here I would consider if the effort is worth digging or implement some dedicate method to your recursion case in directional mapping.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...