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

如何正确实现多级继承多态对象的MapStruct映射

MapStruct 多态DTO与Entity双向映射配置

现有代码结构

DTO层定义

Store类结构:

public class Store   {
     @JsonProperty("name")
      private String name;
      
      @JsonProperty("pets")
      @Valid
      private List<Pet> pets = new ArrayList<>();
      
      // getters/setters
}

Pet基类配置了Jackson多态规则:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type", visible = true)
@JsonSubTypes({
  @JsonSubTypes.Type(value = Cat.class, name = "cat"),
  @JsonSubTypes.Type(value = Dog.class, name = "dog"),
  @JsonSubTypes.Type(value = Pig.class, name = "pig"),
})
public class Pet   {
  public enum TypeEnum {
    CAT("cat"),
    DOG("dog"),
    PIG("pig");
  }
  // 省略type字段、getter/setter
}

Pet子类为空实现:

public class Cat extends Pet{}
public class Dog extends Pet{}
public class Pig extends Pet{}

初始Mapper代码(存在问题)

@Mapper
public interface StoreEntityMapper {
  StoreEntity toStoreEntity(Store store);
  Store to Store(StoreEntity store); // 方法名存在空格笔误
}
@Mapper
public interface PetEntityMapper {
  PetEntity toPetEntity(Pet pet);
  Pet to Pet (PetEntity pet); // 方法名存在空格笔误
}

正确配置方案

前提:Entity层需与DTO层保持对应多态结构,即存在PetEntity基类,以及CatEntity、DogEntity、PigEntity三个子类,PetEntity中需存在type字段区分子类类型。

方案1:MapStruct 1.5+ 版本(推荐,原生支持多态映射)

使用@SubclassMapping注解显式声明所有子类的映射对应关系,MapStruct会自动识别基类引用指向的实际子类类型,完成双向转换。
首先修正Pet映射器:

@Mapper
public interface PetEntityMapper {
    // 基类双向映射,声明所有子类对应关系
    @SubclassMapping(source = Cat.class, target = CatEntity.class)
    @SubclassMapping(source = Dog.class, target = DogEntity.class)
    @SubclassMapping(source = Pig.class, target = PigEntity.class)
    @SubclassMapping(source = CatEntity.class, target = Cat.class)
    @SubclassMapping(source = DogEntity.class, target = Dog.class)
    @SubclassMapping(source = PigEntity.class, target = Pig.class)
    PetEntity toPetEntity(Pet pet);

    Pet toPet(PetEntity pet);

    // 子类具体映射方法,子类有专属字段时直接在方法上加@Mapping注解配置即可
    CatEntity toCatEntity(Cat cat);
    Cat toCat(CatEntity catEntity);

    DogEntity toDogEntity(Dog dog);
    Dog toDog(DogEntity dogEntity);

    PigEntity toPigEntity(Pig pig);
    Pig toPig(PigEntity pigEntity);
}

然后修正Store映射器,引入Pet映射器即可,MapStruct会自动处理List<Pet>集合的多态元素映射:

@Mapper(uses = PetEntityMapper.class)
public interface StoreEntityMapper {
    StoreEntity toStoreEntity(Store store);
    Store toStore(StoreEntity store);
}

方案2:MapStruct 1.5以下版本兼容方案

低版本无@SubclassMapping支持,通过自定义默认方法判断实例类型,结合@IterableMapping指定集合元素映射逻辑实现。
Pet映射器配置:

@Mapper
public interface PetEntityMapper {
    @Named("toPetEntity")
    default PetEntity convertPetToEntity(Pet pet) {
        if (pet instanceof Cat) return toCatEntity((Cat) pet);
        if (pet instanceof Dog) return toDogEntity((Dog) pet);
        if (pet instanceof Pig) return toPigEntity((Pig) pet);
        return null;
    }

    @Named("toPet")
    default Pet convertEntityToPet(PetEntity entity) {
        if (entity instanceof CatEntity) return toCat((CatEntity) entity);
        if (entity instanceof DogEntity) return toDog((DogEntity) entity);
        if (entity instanceof PigEntity) return toPig((PigEntity) entity);
        return null;
    }

    // 子类具体映射方法
    CatEntity toCatEntity(Cat cat);
    Cat toCat(CatEntity catEntity);
    DogEntity toDogEntity(Dog dog);
    Dog toDog(DogEntity dogEntity);
    PigEntity toPigEntity(Pig pig);
    Pig toPig(PigEntity pigEntity);
}

Store映射器需要显式指定集合的映射规则:

@Mapper(uses = PetEntityMapper.class)
public interface StoreEntityMapper {
    StoreEntity toStoreEntity(Store store);
    Store toStore(StoreEntity store);

    @IterableMapping(qualifiedByName = "toPetEntity")
    List<PetEntity> mapPetsToEntities(List<Pet> pets);

    @IterableMapping(qualifiedByName = "toPet")
    List<Pet> mapEntitiesToPets(List<PetEntity> petEntities);
}

注意事项

  • 原有Jackson多态配置与MapStruct映射逻辑完全独立,互不影响,不需要为了映射修改Jackson的序列化/反序列化规则。
  • 初始代码中to Store、to Pet的方法名存在多余空格,需要删除空格改为合法的方法名,否则MapStruct无法识别为映射方法。
  • 如果子类存在专属字段,直接在对应子类的映射方法上添加@Mapping注解配置字段映射规则即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 05:39:15