@AfterMapping 方法未在生成的 class 中调用
@AfterMapping mehod is not called in generated class
我正在尝试自定义映射,使用字符串来确定对象属性,所以我这样写:
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public abstract class ProductMapper {
public abstract ProductInput asProductInputFromIdentifier(String identifier);
@AfterMapping
protected void determineIdentifier(String identifier, @MappingTarget ProductInput out) {
if (StringUtils.contains(identifier, '?')) {
out.setExternalId(identifier);
} else {
out.setInernalId(identifier);
}
}
}
生成的 class 不会调用 determineIdentifier 方法。我通过在 asProductInputFromIdentifier 方法上直接使用 Java 表达式找到了另一个解决方案,但我真的想使用 @AfterMapping[=22= 编写清晰的代码].
@Mapping(target = "externalId", expression = "java( org.apache.commons.lang3.StringUtils.contains(identifier, '|') ? identifier : null )")
@Mapping(target = "internalId", expression = "java( !org.apache.commons.lang3.StringUtils.contains(identifier, '|') ? identifier : null )")
public abstract ProductInput asProductDetailInputFromIdentifier(String identifier);
我不明白为什么它不起作用是因为我的方法参数中没有对象吗?
带有 @AfterMapping
的方法将在 map 方法的末尾执行,它应该具有与 map 方法相同的输入参数,例如下面的示例
@Mapper(
componentModel = "spring",
injectionStrategy = InjectionStrategy.CONSTRUCTOR,
uses = {IdentifierMapper.class})
public interface HistoryMapper {
HistoryDynamo toHistoryDynamo(History history);
@AfterMapping
default void changeReason(History history) {
System.out.println(history.getReason());
}
}
参考 github 相同的工作样本 https://github.com/rakesh-singh-samples/map-struct-samples/tree/stack-question-60523230/src/sample/mapstruct/mapper
MapStruct 不知道如何从 String
映射到 ProductInput
在你的情况下我建议你自己实现映射方法。
例如
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public abstract class ProductMapper {
public ProductInput asProductInputFromIdentifier(String identifier) {
ProductInput out = new ProductInput();
if (StringUtils.contains(identifier, '?')) {
out.setExternalId(identifier);
} else {
out.setInernalId(identifier);
}
return out;
}
}
没有必要使用生命周期回调或特殊的 @Mapping
注释来执行此示例中的简单映射。
为了解决这个问题,我将 ProductInput 添加到抽象方法参数中,如下所示(这不是要求)。正如@Rakesh 在他上面的回答中所解释的那样 带有@AfterMapping 的方法将在 map 方法的末尾执行,它应该具有与 map 方法相同的输入参数,但它可能会让其他人对他们的情况感兴趣:
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public abstract class ProductMapper {
public abstract ProductInput asProductInputFromIdentifier(String identifier, ProductInput out);
@AfterMapping
protected void determineIdentifier(String identifier, @MappingTarget ProductInput out) {
if (StringUtils.contains(identifier, '?')) {
out.setExternalId(identifier);
} else {
out.setInernalId(identifier);
}
}
}
但在我的例子中,我使用了 builder = @Builder(disableBuilder = true) 来关闭 MapStruct 中的“builders”,因为它可以帮助某人 ;) Mapstruct Builder
现在生成的 MapperImpl 调用带注释的 @AfterMapping 方法。
我正在尝试自定义映射,使用字符串来确定对象属性,所以我这样写:
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public abstract class ProductMapper {
public abstract ProductInput asProductInputFromIdentifier(String identifier);
@AfterMapping
protected void determineIdentifier(String identifier, @MappingTarget ProductInput out) {
if (StringUtils.contains(identifier, '?')) {
out.setExternalId(identifier);
} else {
out.setInernalId(identifier);
}
}
}
生成的 class 不会调用 determineIdentifier 方法。我通过在 asProductInputFromIdentifier 方法上直接使用 Java 表达式找到了另一个解决方案,但我真的想使用 @AfterMapping[=22= 编写清晰的代码].
@Mapping(target = "externalId", expression = "java( org.apache.commons.lang3.StringUtils.contains(identifier, '|') ? identifier : null )")
@Mapping(target = "internalId", expression = "java( !org.apache.commons.lang3.StringUtils.contains(identifier, '|') ? identifier : null )")
public abstract ProductInput asProductDetailInputFromIdentifier(String identifier);
我不明白为什么它不起作用是因为我的方法参数中没有对象吗?
带有 @AfterMapping
的方法将在 map 方法的末尾执行,它应该具有与 map 方法相同的输入参数,例如下面的示例
@Mapper(
componentModel = "spring",
injectionStrategy = InjectionStrategy.CONSTRUCTOR,
uses = {IdentifierMapper.class})
public interface HistoryMapper {
HistoryDynamo toHistoryDynamo(History history);
@AfterMapping
default void changeReason(History history) {
System.out.println(history.getReason());
}
}
参考 github 相同的工作样本 https://github.com/rakesh-singh-samples/map-struct-samples/tree/stack-question-60523230/src/sample/mapstruct/mapper
MapStruct 不知道如何从 String
映射到 ProductInput
在你的情况下我建议你自己实现映射方法。
例如
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public abstract class ProductMapper {
public ProductInput asProductInputFromIdentifier(String identifier) {
ProductInput out = new ProductInput();
if (StringUtils.contains(identifier, '?')) {
out.setExternalId(identifier);
} else {
out.setInernalId(identifier);
}
return out;
}
}
没有必要使用生命周期回调或特殊的 @Mapping
注释来执行此示例中的简单映射。
为了解决这个问题,我将 ProductInput 添加到抽象方法参数中,如下所示(这不是要求)。正如@Rakesh 在他上面的回答中所解释的那样 带有@AfterMapping 的方法将在 map 方法的末尾执行,它应该具有与 map 方法相同的输入参数,但它可能会让其他人对他们的情况感兴趣:
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public abstract class ProductMapper {
public abstract ProductInput asProductInputFromIdentifier(String identifier, ProductInput out);
@AfterMapping
protected void determineIdentifier(String identifier, @MappingTarget ProductInput out) {
if (StringUtils.contains(identifier, '?')) {
out.setExternalId(identifier);
} else {
out.setInernalId(identifier);
}
}
}
但在我的例子中,我使用了 builder = @Builder(disableBuilder = true) 来关闭 MapStruct 中的“builders”,因为它可以帮助某人 ;) Mapstruct Builder 现在生成的 MapperImpl 调用带注释的 @AfterMapping 方法。