【问题标题】:How to map extended classes in MapStruct如何在 MapStruct 中映射扩展类
【发布时间】:2020-08-23 11:39:05
【问题描述】:

关于 mapStruct 的问题。我有从基础实体扩展类但不知道如何映射它的情况。这是我的情况。

基础实体:

public class BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "id")
    private Long id;
}

BaseDto:

public class BaseDto {

    private Long id;
}

用户实体:

public class User extends BaseEntity {
    private String name;
    private String lastName;
    private String username;
    private String password;
    private String profilePicturePath;
}

UserDto:

public class UserDto extends BaseDto {
    private String name;
    private String lastName;
    private String username;
    private String password;
    private String profilePicturePath;
}

而mapper是这样的:

@Mapper(uses = {BaseMapper.class})
public interface UserMapper {

    User userDtoToUser(UserDto userDto);

    UserDto userToUserDto(User user);
}

BaseMapper:

@Mapper
public interface BaseMapper {

    BaseEntity dtoToEntity(BaseDto baseDto);

    BaseDto entityToDto(BaseEntity baseEntity);
}

问题是我没有映射 ID 属性。

感谢您的宝贵时间。

编辑:

没有显示错误,在映射器实现(生成的代码)中没有该 ID 的映射:

 @Override
    public User userDtoToUser(UserDto userDto) {
        if ( userDto == null ) {
            return null;
        }

        UserBuilder user = User.builder();

        user.name( userDto.getName() );
        user.lastName( userDto.getLastName() );
        user.username( userDto.getUsername() );
        user.password( userDto.getPassword() );
        user.profilePicturePath( userDto.getProfilePicturePath() );

        return user.build();
    }

【问题讨论】:

  • 嘿鬼猫。我已对原始问题添加了编辑。没有显示任何错误,我看到实现缺少 ID 映射,并且当我运行程序时,我在 UserDto 对象中,ID 为空。
  • 你怎么称呼这个映射器?
  • 它在课堂上是自动装配的,我像这样调用它 return userMapper.userToUserDto(savedUser);其中保存的用户是用户对象
  • 你可以为 builder 添加代码吗?你在用龙目岛吗?
  • 是的,我正在使用 lombok。并且我在 pom 中添加了必要的配置,所以 mapstruct 和 lombok 可以一起玩。还有一件事,在生成的代码中,我看到基本映射器像这样自动装配@Autowired private BaseMapper baseMapper;

标签: java mapstruct


【解决方案1】:

我猜(因为您没有输入buider 代码)问题是您的构建器类不包含父类字段。 MapStruct 在为映射器生成代码时做了一些假设。来自documentation -

BuilderProvider 的默认实现假定 以下:

  1. 该类型有一个无参数的公共静态构建器创建方法 返回一个构建器。因此,例如 Person 有一个公共静态 返回 PersonBuilder 的方法。
  2. builder 类型有一个无参数的公共方法(build 方法) 返回正在构建的类型 在我们的示例中 PersonBuilder 有一个 方法返回 Person。
  3. 如果有多个构建方法,MapStruct 将寻找一个 称为 build 的方法,如果存在这样的方法,那么将使用它, 否则会产生编译错误。

如果您使用的是 Lombok,您可以使用 @SuperBuilder as 来解决这个问题 -

@SuperBuilder
@Getter
@ToString
public class UserDto extends BaseDto {
  private String name;
  private String lastName;
  private String username;
  private String password;
  private String profilePicturePath;
}

@Getter
@SuperBuilder
class BaseDto {
  private Long id;
}

@SuperBuilder
@Getter
@ToString
public class User extends BaseEntity {
  private String name;
  private String lastName;
  private String username;
  private String password;
  private String profilePicturePath;
}

@Setter
@Getter
@SuperBuilder
class BaseEntity {
  private Long id;
}

生成的可能看起来像 -

@Override
public User userDtoToUser(UserDto userDto) {
    if ( userDto == null ) {
        return null;
    }

    UserBuilder<?, ?> user = User.builder();

    user.id( userDto.getId() );
    user.name( userDto.getName() );
    user.lastName( userDto.getLastName() );
    user.username( userDto.getUsername() );
    user.password( userDto.getPassword() );
    user.profilePicturePath( userDto.getProfilePicturePath() );

    return user.build();
}

【讨论】:

  • 我想在BaseDto,BaseEntity类中添加@NoArgsConstructor@AllArgsConstructor
猜你喜欢
  • 2021-08-03
  • 1970-01-01
  • 1970-01-01
  • 2019-07-16
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多