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

Model Mapper转换DTO到实体时字段值映射错误的解决办法

问题描述

我有一个名为MasterEntity的实体,它与ChildEntity实体是单向一对一关联,数据库映射代码如下:

@Entity(name = "MasterEntity")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MasterEntity {
 
    @Id
    private Integer Id;
    private String Name;
    private String Division;

    @OneToOne
    @MapsId
    @JoinColumn(name = "Id")
    private ChildEntity childEntity;

}

@Entity(name = "childEntity")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ChildEntity {
 
    @Id
    private Integer Id;
    private String MatchingName;

}

同时我有一个MasterEntityDTO,字段定义如下:

@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MasterEntityDTO {
 
    private Integer Id;
    private String Name;
    private String Division;

}

我尝试用ModelMapper将DTO映射为实体,设置匹配策略为LOOSE(后续计划给DTO添加映射到childEntity的字段),代码如下:

masterEntityDTO.setName("Jonathan");

ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.LOOSE);

modelMapper.map(masterEntityDTO, MasterEntity.class);

得到的实体结果却出现错误:MatchingName被填充了Name的值:

Id = null
Name = "Jonathan"
Division = null
Id = null
MatchingName = "Jonathan"

尝试过不同ModelMapper配置都无法解决,该如何修复?

解决方案

方法1:显式忽略ChildEntity的MatchingName字段映射

通过添加映射规则,阻止ModelMapper自动匹配Name到MatchingName:

ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.LOOSE);

// 显式跳过ChildEntity的MatchingName字段映射
modelMapper.addMappings(mapper -> {
    mapper.forMember(dest -> dest.getChildEntity().setMatchingName(), opt -> opt.skip());
});

MasterEntity masterEntity = modelMapper.map(masterEntityDTO, MasterEntity.class);

方法2:调整匹配策略为STANDARD(推荐)

改用规则更严格的STANDARD策略,它不会把Name和MatchingName错误关联:

ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STANDARD);

MasterEntity masterEntity = modelMapper.map(masterEntityDTO, MasterEntity.class);

后续需要给DTO添加ChildEntity相关字段时,再针对性配置映射规则即可。

方法3:自定义字段映射规则

通过TypeMap明确指定DTO到实体的映射字段,避免自动匹配:

ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.LOOSE);

TypeMap<MasterEntityDTO, MasterEntity> typeMap = modelMapper.createTypeMap(MasterEntityDTO.class, MasterEntity.class);
// 只映射指定字段
typeMap.addMapping(MasterEntityDTO::getId, MasterEntity::setId);
typeMap.addMapping(MasterEntityDTO::getName, MasterEntity::setName);
typeMap.addMapping(MasterEntityDTO::getDivision, MasterEntity::setDivision);
// 不映射childEntity相关字段
typeMap.addMapping(src -> null, MasterEntity::setChildEntity);

MasterEntity masterEntity = typeMap.map(masterEntityDTO);

方法4:修改字段命名(如果允许)

如果可以调整实体字段名,把MatchingName改成和DTO无关联的命名(比如ChildName),从根源避免自动匹配问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 06:37:32