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

ModelMapper映射DTO与实体时location_id为空触发非空约束报错如何解决?

问题根因

Person实体的location字段是Location实体类型,而PersonDTO的location字段是Long类型的主键ID,ModelMapper默认没有对应类型转换规则,导致映射后Person的location属性为null,触发数据库location_id字段非空约束报错。


解决方案

方案1:注册全局类型转换器(推荐,可复用)

自定义Long转Location的转换器并注册到ModelMapper,所有涉及该类型转换的场景都可以复用:

// 首先在Service中注入LocationRepository
@Autowired
private LocationRepository locationRepository;

// 项目启动时注册转换器(可放在ModelMapper配置类或当前Service的初始化方法中)
@PostConstruct
public void initModelMapper() {
    Converter<Long, Location> longToLocationConverter = context -> {
        Long locationId = context.getSource();
        if (locationId == null) {
            return null;
        }
        // 可根据业务需求调整不存在时的处理逻辑
        return locationRepository.findById(locationId)
                .orElseThrow(() -> new RuntimeException("关联Location不存在,ID:" + locationId));
    };
    modelMapper.addConverter(longToLocationConverter);
}

配置完成后原有转换逻辑无需修改即可正常映射。


方案2:手动补全关联属性(简单直接,适合单场景使用)

无需全局配置,直接在转换方法中手动查询并赋值location属性:

// 首先在Service中注入LocationRepository
@Autowired
private LocationRepository locationRepository;

private Person convertToPerson2(PersonDTO personDTO) {
    modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.LOOSE);
    Person person = modelMapper.map(personDTO, Person.class);
    // 手动设置location属性
    if (personDTO.getLocation() != null) {
        Location location = locationRepository.findById(personDTO.getLocation())
                .orElseThrow(() -> new RuntimeException("关联Location不存在,ID:" + personDTO.getLocation()));
        person.setLocation(location);
    }
    return person;
}

方案3:调整DTO结构实现隐式映射(无需额外查库)

修改DTO结构匹配实体层级,ModelMapper可自动映射ID属性,Hibernate会直接关联已存在的Location记录:

@Data
public class PersonDTO {
    private String username;
    private String firstName;
    private String lastName;
    // 调整为嵌套结构匹配实体层级
    private LocationIdDTO location;

    @Data
    public static class LocationIdDTO {
        private Long id;
    }
}

对应请求参数调整为:

{
    "username":"bulbul",
    "firstName":"Bulbul",
    "lastName":"Ahmed",
    "location":{
        "id":1
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:30:04