我写了一个 mapstruct 映射器,它使用这样的映射:
@Mapping(target = "userId", source = "id.userId")
当我查看自动生成的 mapstruct 类时,我偶然发现了该代码:
if ( !foobar.hasId() ) {
return null;
}
这对我来说是个问题,因为
hasId()
不是 mapstruct 在这里所期望的。我可以强制 mapstruct 以某种方式不生成使用此方法但检查 id != null
或其他东西的代码吗?
我可以使用像
@Mapping(target = "userId", expression= "java(...)")
这样的映射,但我认为应该有另一种方式。
是的,您可以强制 MapStruct 不使用那些
presenceCheckers
。您可以在文档中的source presence checking中找到更多信息。
AccessorNamingStrategy
的实现。您可以只扩展DefaultAccessorNamingStrategy
并覆盖它的isPresenceCheckMethod
。
您可以访问该方法
ExecutableElement
,您可以检查它所在的类的类型以及其他内容。
MyAccessorNamingStrategy extends DefaultAccessorNamingStrategy {
@Override
public boolean isPresenceCheckMethod(ExecutableElement element) {
//You can do your checks here. You can ignore certain methods, from certain classes
}
记得用文件注册你的SPI
META-INF-/services/com.example.MyAccessorNamingStrategy
还有 examples,您可以在其中找到 SPI 的示例。
虽然建议提供您自己的AccessorNamingStrategy
的
answer解释了一般如何解决这个问题,但通常禁用源存在检查器是矫枉过正的。我认为您使用
expression
的解决方案在一次性覆盖的简单性方面可能通常是正确的答案。
@Mapping(target = "userId", expression="java(source.getId().getUserId())")
MyTargetType map(MySourceType source);
或
@Mapping(target = "userId", source="id")
MyTargetType map(MySourceType source);
default String map(MySourceTypeId id) {
return id == null ? null : id.getUserId();
}
MapStruct 将
hasId()
方法视为 source presence checker 方法,仅在返回 id
时才设置 true
值。
如果指定
conditionExpression
,则使用它代替源存在检查器方法。通过为此指定一个始终为真的值,该值将始终被映射,而不是有条件地基于hasId()
.的结果
@Mapping(target = "userId", source = "id.userId", conditionExpression = "java(true)")
这导致生成的代码如下所示:
if ( true ) {
target.setUserId( userId );
}