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

MapStruct与Lombok:如何避免映射器生成时使用无参构造方法?

MapStruct使用问题:自定义构造方法未生效+Fluent Setter未被调用

尽管我的DTO和实体类中存在无参构造方法(jsonb、JPA、JAXB等通常要求该构造方法),但我希望MapStruct不要使用无参构造方法。

我的DepartmentDTO实现如下:

@RequiredArgsConstructor
@NoArgsConstructor(access = PROTECTED)
@Getter
@Accessors(fluent = true)
public class DepartmentDTO
{
    @NonNull @Setter private String name;

    public DepartmentDTO(@NonNull DepartmentEntity department, @NonNull MapStructContext context)
    {
        this(department.name());
        log.debug("context {}", context);
    }
}

对应的DepartmentEntity类实现类似。

我在映射器接口中实现了标注@ObjectFactory的方法,用于调用带参的自定义构造方法,但MapStruct仍在使用无参构造方法:

@Mapper
public interface MapStructMapper
{
    MapStructMapper INSTANCE = Mappers.getMapper(MapStructMapper.class);

    DepartmentEntity map(DepartmentDTO    department, MapStructContext context);
    DepartmentDTO    map(DepartmentEntity department, MapStructContext context);

    @ObjectFactory
    default DepartmentDTO create(
            @NonNull DepartmentEntity department, @NonNull @Context MapStructContext context)
    {
        return new DepartmentDTO(department, context);
    }


    @ObjectFactory
    default DepartmentEntity create(
            @NonNull DepartmentDTO department, @NonNull @Context MapStructContext context)
    {
        return new DepartmentEntity(department, context);
    }

    @ToString
    class MapStructContext
    {
        private Map<Object, Object> knownInstances = new IdentityHashMap<Object, Object>();

        @BeforeMapping
        public <T> T getMappedInstance(Object source, @TargetType Class<T> targetType) {
            return (T) knownInstances.get( source );
        }

        @BeforeMapping
        public void storeMappedInstance(Object source, @MappingTarget Object target) {
            knownInstances.put( source, target );
        }
    }

}

上下文参数用于在自定义构造方法中正确处理循环依赖。以下是生成代码的部分内容:

public DepartmentEntity map(DepartmentDTO department, MapStructMapper.MapStructContext context) {
    if (department == null && context == null) {
      return null;
    } else {
      DepartmentEntity departmentEntity = new DepartmentEntity();
      return departmentEntity;
    }
  }

  public DepartmentDTO map(DepartmentEntity department, MapStructMapper.MapStructContext context) {
    if (department == null && context == null) {
      return null;
    } else {
      DepartmentDTO departmentDTO = new DepartmentDTO();
      return departmentDTO;
    }
  }

请问我忽略了什么?

另外,DTO和实体类中存在Lombok生成的fluent风格setter方法,为什么生成的映射器中没有调用它们?


内容的提问来源于stack exchange,提问作者r-uu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 15:15:27