MapStruct泛型Map和map组合的子对象列表

时间:2016-09-29 15:07:37

标签: java oop inheritance polymorphism mapstruct

我有父类:User.java和2个类:FacebookUser.javaTwitterUser.java它们是返回的实体,取决于使用DiscriminatorColumn的数据库中的类型列,I想要编写正确的映射器来映射可能是FacebookUser或TwitterUser实例的用户。我有以下映射器似乎无法正常工作,只映射User父级而不是子级:

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

    User map(UserDTO userDTO);

    @InheritInverseConfiguration
    UserDTO map(User user);

    List<UserDTO> map(List<User> users);

    FacebookUser map(FacebookUserDTO userDTO);

    @InheritInverseConfiguration
    FacebookUserDTO map(FacebookUser user);

    TwitterUser map(TwitterUserDTO userDTO);

    @InheritInverseConfiguration
    TwitterUserDTO map(TwitterUser user);

}

然后我用:

UserDTO userDto = UserMapper.INSTANCE.map(user);

要映射的类:

@Entity
@Table(name = "users")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING, length = 10)
@DiscriminatorValue(value = "Local")
public class User {
    @Column
    private String firstName;
    @Column
    private String lastName;
    ///... setters and getters
}

@Entity
@DiscriminatorValue(value = "Facebook")
public class FacebookUser extends User {
    @Column
    private String userId;
    ///... setters and getters
}

@Entity
@DiscriminatorValue(value = "Twitter")
public class TwitterUser extends User {
    @Column
    private String screenName; 
    ///... setters and getters
}

DTO:

public class UserDTO {
    private String firstName;
    private String lastName;
    ///... setters and getters
}

public class FacebookUserDTO extends UserDTO {
    private String userId;
    ///... setters and getters
}

public class TwitterUserDTO extends UserDTO {
    private String screenName; 
    ///... setters and getters
}

此外,如果我有与Facebook用户和Twitter用户或基本用户混合的用户列表:

假设我有以下用户:

User user = new User ("firstName","lastName");
User fbUser = new FacebookUser ("firstName","lastName","userId");
User twUser = new TwitterUser ("firstName","lastName","screenName");

List<User> users = new ArrayList<>();
users.add(user);
users.add(fbUser);
users.add(twUser);

//Then: 

List<UserDTO> dtos = UserMapper.INSTANCE.map(users);

我只获得firstNamelastName,但不是screenNameuserId

对此有何解决方案?

1 个答案:

答案 0 :(得分:4)

目前它似乎尚未作为mapstruct的功能提供:Support for Type-Refinement mapping (or Downcast Mapping)

我在谷歌小组中提出了这个问题:https://groups.google.com/forum/?fromgroups#!topic/mapstruct-users/PqB-g1SBTPg

发现我需要在接口内部使用require 'capistrano/puma'方法进行手动映射(对于java 8)。

还有另一个问题,即映射父类几乎不适用,所以我写了一个空类,即父类的子类:

所以代码变得如下:

default