强制 mapstruct 不调用 has* 方法

问题描述 投票:0回答:3

我写了一个 mapstruct 映射器,它使用这样的映射:

@Mapping(target = "userId", source = "id.userId")

当我查看自动生成的 mapstruct 类时,我偶然发现了该代码:

if ( !foobar.hasId() ) {
    return null;
}

这对我来说是个问题,因为

hasId()
不是 mapstruct 在这里所期望的。我可以强制 mapstruct 以某种方式不生成使用此方法但检查
id != null
或其他东西的代码吗?

我可以使用像

@Mapping(target = "userId", expression= "java(...)")
这样的映射,但我认为应该有另一种方式。

java mapping mapstruct
3个回答
5
投票

是的,您可以强制 MapStruct 不使用那些

presenceCheckers
。您可以在文档中的source presence checking中找到更多信息。

基本上唯一的方法是提供 MapStruct

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 的示例。


0
投票

虽然建议提供您自己的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();
}

0
投票

MapStruct 将

hasId()
方法视为 source presence checker 方法,仅在返回
id
时才设置
true
值。

如果指定

conditionExpression
,则使用它代替源存在检查器方法。通过为此指定一个始终为真的值,该值将始终被映射,而不是有条件地基于
hasId()
.

的结果
@Mapping(target = "userId", source = "id.userId", conditionExpression = "java(true)")

这导致生成的代码如下所示:

if ( true ) {
    target.setUserId( userId );
}
© www.soinside.com 2019 - 2024. All rights reserved.