Is it possible to map with Mapstruct an attribute of object B to attribute of object A_DTO, when object A contains a reference to object B?

huangapple go评论83阅读模式
英文:

Is it possible to map with Mapstruct an attribute of object B to attribute of object A_DTO, when object A contains a reference to object B?

问题

According to Mapstruct documentation, it is possible to map an object (object A) that contains another object (object B) by defining a mapping method for the referenced object (object B). However, if you need to map only an attribute of that object (object B) and not the whole object, here's how you can do it with Java and Mapstruct:

@Mapper
public interface AppUserMapper {
    AppUserMapper INSTANCE = Mappers.getMapper(AppUserMapper.class);

    @Mapping(target = "authorities", source = "roles", qualifiedByName = "mapToAuthorities")
    AppUserDetailsDTO toAppUserDetailsDTO(AppUserEntity appUserEntity);

    @Named("mapToAuthorities")
    default Collection<GrantedAuthority> mapToAuthorities(Set<RoleEntity> roles) {
        return roles.stream()
            .map(role -> new SimpleGrantedAuthority(role.getName()))
            .collect(Collectors.toList());
    }
}

In the code above, we define a custom mapping method called "mapToAuthorities" and use it to map the "roles" attribute of "AppUserEntity" to the "authorities" attribute of "AppUserDetailsDTO." This method converts the "RoleEntity" objects into "GrantedAuthority" objects, effectively mapping only the "name" attribute.

Make sure to use the @Mapper annotation from Mapstruct to generate the implementation of this mapping interface.

Please note that you should adjust the code to match your project's package structure and dependencies.

英文:

According to Mapstruct documentation it is possible to map to DTO an object (object A) that contains another object (object B) by defining a mapping method for the referenced object (object B). But what if I need to map only attribute of that object (object B) and not the whole object?

Describing problem -
I am studing the Spring Boot and here is my project - https://github.com/Alex1182-St/java-spring-jpa-postgresql

With purpose of security I need to map my AppUserEntity to AppUserDetailsDTO (implements UserDetails) and especially I need to map the name from the attribute private Set&lt;RoleEntity&gt; roles of my AppUserEntity to the private Collection&lt;GrantedAuthority&gt; authorities of my AppUserDetailsDTO

With Kotlin it is easy (authorities = roles.map { it.name }):

    fun AppUserEntity.toAppUserDetailsDTO() = AppUserDetailsDTO(
            id = id,
            username = appUserLogin,
            password = appUserPassword,
            authorities = roles.map { it.name },
            isEnabled               = isEnabled,
            isAccountNonLocked      = isAccountNonLocked,
            isAccountNonExpired     = isAccountNonExpired,
            isCredentialsNonExpired = isCredentialsNonExpired
    )

But How to do it with Java and Mapstruct?

答案1

得分: 2

On Mapstruct a method can be used for the mapping on the annotations using the expression property on the annotation: expression = "java( yourJavaCodeHere )".

Your mapper would look like:

@Mapper(componentModel = "spring")
public abstract class AppUserDetailsDtoMapper {

    @Mappings({
            @Mapping(target = "username", source = "appUserLogin"),
            @Mapping(target = "password", source = "appUserPassword"),
            @Mapping(target = "authorities", expression = "java( mapAuthorities(user.getRoles()) )")
    })
    public abstract AppUserDetailsDTO toAppUserDetailsDTO(AppUserEntity user);

    protected Collection<GrantedAuthority> mapAuthorities(Set<RoleEntity> roles) {
        // Map the authorities here
    }
}
英文:

On Mapstruct a method can be used for the mapping on the annotations using the expression property on the annotation: expression = &quot;java( yourJavaCodeHere )&quot;.

Your mapper would look like:

@Mapper(componentModel = &quot;spring&quot;)
public abstract class AppUserDetailsDtoMapper {

    @Mappings({
            @Mapping(target = &quot;username&quot;, source = &quot;appUserLogin&quot;),
            @Mapping(target = &quot;password&quot;, source = &quot;appUserPassword&quot;),
            @Mapping(target = &quot;authorities&quot;, expression = &quot;java( mapAuthorities(user.getRoles()) )&quot;)
    })
    public abstract AppUserDetailsDTO toAppUserDetailsDTO(AppUserEntity user);

    protected Collection&lt;GrantedAuthority&gt; mapAuthorities(Set&lt;RoleEntity&gt; roles) {
        // Map the authorities here
    }
}

huangapple
  • 本文由 发表于 2020年8月12日 16:37:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/63372853.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定