ModelMapper实现DTO转Entity提示无无参构造报错如何解决
错误原因
- ModelMapper默认优先调用目标类的无参构造实例化对象,再反射赋值字段。你的
Member类仅配置了@RequiredArgsConstructor,仅生成包含所有final修饰字段的构造方法,无可用无参构造,因此触发无参构造不存在的报错。 - 你尝试直接映射到
MemberBuilder的写法缺少ModelMapper的Builder适配配置,无法正常识别Lombok生成的Builder类的赋值方法。
修复方案
方案1:适配Builder映射(推荐,无需修改实体类构造规则)
- 调整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; }
- 调整转换方法写法:
private Member convertToEntity(UserMetaData dto) { Member.MemberBuilder<?, ?> builder = modelMapper.map(dto, Member.MemberBuilder.class); return builder.id(UUID.randomUUID()).build(); }
方案2:新增无参构造兼容默认映射逻辑
如果方案1适配仍有问题,可直接给实体类添加无参构造,走默认实例化赋值逻辑:
- 给
Member类添加@NoArgsConstructor注解,force参数设置为true兼容final字段:
@Document(collection = "Users") @SuperBuilder @Data @RequiredArgsConstructor(onConstructor = @__(@PersistenceConstructor)) @NoArgsConstructor(force = true) // 新增注解,final字段会被初始化为对应类型的默认值 public class Member implements User { // 原有字段、方法保持不变 }
- 调整转换方法,反射赋值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
相关产品推荐
相关产品推荐

