2016-09-29 33 views
3

我作为父类:User.java和2类:FacebookUser.javaTwitterUser.java他们是返回使用DiscriminatorColumn取决于数据库的类型列,我想写正确映射到实体映射可能是FacebookUser或TwitterUser实例的用户。我有以下的映射,这似乎并不如预期运作,唯一的映射的User父母不是孩子:MapStruct通用的地图和儿童的地图组合列表对象

@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

任何解决方案?

回答

3

目前它似乎其尚未公布的功能对于mapstruct:Support for Type-Refinement mapping (or Downcast Mapping)

我问的问题在他们的谷歌组:https://groups.google.com/forum/?fromgroups#!topic/mapstruct-users/PqB-g1SBTPg

,我发现我需要使用default方法做内部接口手动映射(对于Java 8)。

,并得到映射父另一个问题是几乎不适用,所以我写一个空洞的类,父类的子:

所以代码变成像下面这样:

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

    LocalUser map(LocalUserDTO userDTO); 

    @InheritInverseConfiguration 
    LocalUserDTO map(LocalUser 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); 

    default UserDTO map(User user) { 

     if (user instanceof FacebookUser) { 
      return this.map((FacebookUser) user); 
     } else if (user instanceof TwitterUser) { 
      return this.map((TwitterUser) user); 
     } else { 
      return this.map((LocalUser) user); 
     } 
    } 

    @InheritInverseConfiguration 
    default User map(UserDTO userDTO) { 
     if (userDTO instanceof FacebookUserDTO) { 
      return this.map((FacebookUserDTO) userDTO); 
     } else if (userDTO instanceof TwitterUserDTO) { 
      return this.map((TwitterUserDTO) userDTO); 
     } else { 
      return this.map((LocalUserDTO) userDTO); 
     } 
    } 

}