映射目标使用继承时如何重用现有映射器

How to reuse existing mapper when mapping target uses Inheritance

我有 Inventory class 和 InventoryResponse class。

public class Inventory {
  private InventoryStatus inventoryStatus;
}

public class InventoryResponse {
  private string inventoryStatus;    
}

我能够使用映射器创建从 Inventory 到 InventoryResponse 的映射。

@JsonInclude(JsonInclude.Include.NON_NULL)
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)

public abstract class InventoryResponseMapper {

  @Mapping(source = "inventoryStatus.inventoryStatusCd", target = "inventoryStatus")
  public abstract InventoryResponse toInventoryResponse(Inventory inventory);

}

现在,我有一个新版本的响应,InventoryResponseV1,它有一个额外的 属性,叫做 inventoryId。为了重复使用,我扩展了 InventoryResponse class.

public class InventoryResponseV1 extends InventoryResponse {
   private String inventoryId;
}

现在,为了将 Inventory 映射到 InventoryResponseV1,我想重新使用 InventoryResponseMapper class,通过使用 uses = {InventoryResponseMapper.class}

@JsonInclude(JsonInclude.Include.NON_NULL)
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, uses = {InventoryResponseMapper.class})

public interface InventoryResponseV1Mapper {
    @Mapping(target = "inventoryId", expression = "java(java.util.UUID.randomUUID())")
    InventoryResponseV1 toInventoryResponseV1(Inventory inventory);
}

我的期望是,从 Inventory 到 InventoryResponseV1 的所有现有映射都将使用 InventoryResponseMapper 解决(InventoryResponseV1 是 InventoryResponse)。

映射失败并出现以下错误:

error: Can't map property "com.myOrg.InventoryStatus inventoryStatus" to "java.lang.String inventoryStatus". Consider to declare/implement a mapping method: "java.lang.String map(com.myOrg.InventoryStatus value)". InventoryResponseV1 toInventoryResponseV1(Inventory product);

这种期望是否不正确,采用 mapstruct into account? I have also tried using @DecoratedWith,但意识到它有不同的用例。

为了重用这样的配置,您需要使用 MapperConfig

因此,在您的用例中,您可以执行以下操作:

@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, config = InventoryResponseMapper.class)
public interface InventoryResponseV1Mapper {

    @Mapping(target = "inventoryId", expression = "java(java.util.UUID.randomUUID())")
    @InheritConfiguration
    InventoryResponseV1 toInventoryResponseV1(Inventory inventory);

}

你也可以让你的其他映射器成为一个配置

例如

@MapperConfig
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
public abstract class InventoryResponseMapper {

  @Mapping(source = "inventoryStatus.inventoryStatusCd", target = "inventoryStatus")
  public abstract InventoryResponse toInventoryResponse(Inventory inventory);

}