You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ModelMapper实现DTO转Entity提示无无参构造报错如何解决

错误原因

  • ModelMapper默认优先调用目标类的无参构造实例化对象,再反射赋值字段。你的Member类仅配置了@RequiredArgsConstructor,仅生成包含所有final修饰字段的构造方法,无可用无参构造,因此触发无参构造不存在的报错。
  • 你尝试直接映射到MemberBuilder的写法缺少ModelMapper的Builder适配配置,无法正常识别Lombok生成的Builder类的赋值方法。

修复方案

方案1:适配Builder映射(推荐,无需修改实体类构造规则)

  1. 调整ModelMapper配置,开启Builder映射支持:
@Bean
public ModelMapper modelMapper() {
    ModelMapper modelMapper = new ModelMapper();
    modelMapper.getConfiguration()
            .setFieldMatchingEnabled(true)
            .setFieldAccessLevel(org.modelmapper.config.Configuration.AccessLevel.PRIVATE)
            // 新增Builder适配配置
            .setDestinationNamingConvention(NamingConventions.builder())
            .setMethodAccessLevel(org.modelmapper.config.Configuration.AccessLevel.PUBLIC);
    return modelMapper;
}
  1. 调整转换方法写法:
private Member convertToEntity(UserMetaData dto) {
    Member.MemberBuilder<?, ?> builder = modelMapper.map(dto, Member.MemberBuilder.class);
    return builder.id(UUID.randomUUID()).build();
}

方案2:新增无参构造兼容默认映射逻辑

如果方案1适配仍有问题,可直接给实体类添加无参构造,走默认实例化赋值逻辑:

  1. 给Member类添加@NoArgsConstructor注解,force参数设置为true兼容final字段:
@Document(collection = "Users")
@SuperBuilder
@Data
@RequiredArgsConstructor(onConstructor = @__(@PersistenceConstructor))
@NoArgsConstructor(force = true) // 新增注解,final字段会被初始化为对应类型的默认值
public class Member implements User {
    // 原有字段、方法保持不变
}
  1. 调整转换方法,反射赋值final修饰的id字段:
private Member convertToEntity(UserMetaData dto) throws NoSuchFieldException, IllegalAccessException {
    Member member = modelMapper.map(dto, Member.class);
    // 手动赋值id
    Field idField = Member.class.getDeclaredField("id");
    idField.setAccessible(true);
    idField.set(member, UUID.randomUUID());
    return member;
}

内容的提问来源于stack exchange,提问作者TheNope

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 22:36:04