Mapper 找不到它所依赖的另一个映射器

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

我有两个映射器,

MapperOne
MapperTwo
,后者取决于前者:

@Mapper(componentModel = "spring")
public interface MapperOne {

    UserDTO convert(User user);
}

@Mapper(componentModel = "spring", uses = MapperOne.class)
public interface MapperTwo {

    @Mapping(target = "loginUser", source = "user")
    UserDTO convert(Login login);
}

MapperTwo
按预期工作,但我们假设第三个映射器使用
MapperTwo
,如下所示:

import static org.mapstruct.factory.Mappers.getMapper;

@Mapper(componentModel = "spring")
public interface MapperThree {

    default UserDTO convert(@NonNull final LoginWrapper loginWrapper) {
        final Login login = loginWrapper.getInstance();
        return getMapper(MapperTwo.class).convert(login);
    }
}

MapperThree
不起作用,我总是收到以下错误消息:

java.lang.NullPointerException:无法调用 “com.mytest.mappers.MapperOne.convert(com.mytest.User)”因为 “this.mapperOne”为空

java mapstruct
2个回答
0
投票

当您使用

componentModel = "spring"
时,您不应该使用
Mappers.getMapper
。使用通常的
@Autowired
或通过构造函数进行依赖注入应该可以。这可能就是您的案例遇到问题的原因。只需使用
uses = {SomeMapper.class}
就可以了。当类型适用时,Mapstruct 将自动使用“已使用”映射器的映射。

如果您想真正在另一个映射器中编写默认函数,那么您应该使用抽象类并像往常一样自动装配另一个映射器。

@Mapper(componentModel = "spring")
public abstract class MapperThree {

    @Autowired
    MapperTwo mapperTwo;

    default UserDTO convert(@NonNull final LoginWrapper loginWrapper) {
        final Login login = loginWrapper.getInstance();
        return mapperTwo.convert(login);
    }
}

0
投票

在 pom.xml 中定义属性: 将属性添加到您的 pom.xml 中:

<properties>
  <mapstruct.defaultComponentModel>spring</mapstruct.defaultComponentModel>
</properties>

配置Maven编译器插件: 添加配置以将此属性传递给注释处理器,这样您就不必在每个映射器中重复包含 componentModel=spring :

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version> <!-- Use the appropriate version -->
            <configuration>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>1.5.5.Final</version>
                    </path>
                </annotationProcessorPaths>
                <annotationProcessorOptions>
                    <mapstruct.defaultComponentModel>${mapstruct.defaultComponentModel}</mapstruct.defaultComponentModel>
                </annotationProcessorOptions>
            </configuration>
        </plugin>
    </plugins>
</build>

MapperOne不需要改变。

@Mapper
public interface MapperOne {
  UserDTO convert(User user);
}

MapperTwo:您能否确认所需的返回值是 UserDTO 而不是 LoginDTO 或类似的值?

@Mapper(uses = {MapperOne.class})
public interface MapperTwo {

  @Mapping(target = "loginUser", source = "user")
  UserDTO convert(Login login);
}

假设您需要一些转换器方法并希望依赖于另一个映射器,您可以定义一个抽象类并通过 setter 注入自动装配。

@Mapper(uses = MapperTwo.class)
public abstract class MapperThree {

  protected MapperTwo mapperTwo;

  @Autowired
  public final void setMapperTwo(MapperTwo mapperTwo) {
     this.mapperTwo = mapperTwo;
  }

   UserDTO convert(@NonNull final LoginWrapper loginWrapper) {
    final Login login = loginWrapper.getInstance();
    return mapperTwo.convert(login);
  }

}
© www.soinside.com 2019 - 2024. All rights reserved.