映射目标使用继承时如何重用现有映射器
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);
}
我有 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);
}