2016-09-29 34 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); 
     } 
    } 

}