【问题标题】:How can I use spring injection, A repository class in a mapstruct mapper?如何使用 spring 注入,mapstruct 映射器中的存储库类?
【发布时间】:2020-08-04 09:01:21
【问题描述】:
@Data
public class FilesDTO {

    private int issue;
    private String uniqueStr;
    private StorageDomain xml;
    private StorageDomain pdf;
    private StorageDomain stop;
}
@Data
public class BackHalfDomain {
    private int articleId;
    private String uniqueStrr;
    private long xmlContentId;
    private long pdfContentId;
    private long stopId;
    private int issueNumber;
}

使用存储库类,我必须从 BackHalfDomain 中的 ID 获取 StorageDomain 对象。所以我必须将StorageDomain 对象映射到相应的字段。 像StorgeDomain sd = repo.findById(id).get(); 并在FilesDTO 的xml 字段中设置这个sd 对象等等。 这是我的映射器

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

    public static final FilesDTOMapper fileDTOMapper = Mappers.getMapper(FilesDTOMapper.class);

    @Mapping(target = "issue", source = "domain.issueNumber")
    @Mapping(target = "DOI", source = "domain.doi")
    public FilesDTO map(BackHalfDomain domain);

}

我使用了uses,但没有成功。 我用过@Mapping(target="xyz", expression="java(repo.findById(id))")" 但我得到的只是NullPointerException 弹簧注入不起作用。 有人可以解决这个问题吗?我刚开始mapstruct

【问题讨论】:

标签: java spring mapping mapstruct mapper


【解决方案1】:

从 mapstruct 1.2 开始,您可以使用 @AfterMapping 和 @Context 的组合。

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

   @Mapping(target = "xyz", ignore = true)
   @Mapping(target = "issue", source = "domain.issueNumber")
   @Mapping(target = "DOI", source = "domain.doi")
   FilesDTO map( BackHalfDomain domain, @Context MyRepo repo);

   @AfterMapping
   default void map( @MappingTarget FilesDTO target, BackHalfDomain domain, @Context MyRepo repo) {
        target.setXYZ(repo.findById(domain.getId()));
   }
 }

在 1.1 中,您需要将映射器转换为抽象类

@Mapper(unmappedTargetPolicy = org.mapstruct.ReportingPolicy.IGNORE,
        componentModel = "spring",
        uses = {})
public abstract class FilesDTOMapper {

    @Autowired
    protected MyRepo repo;


    @Mapping(target = "issue", source = "domain.issueNumber")
    @Mapping(target = "DOI", source = "domain.doi")
    @Mapping(target="xyz", expression="java(repo.findById(domain.getId())))")
    public FilesDTO map(BackHalfDomain domain);

}

【讨论】:

  • 我正在使用 mapstruct 版本 1.3.0 但是这个方法也没有得到我的结果。 FilesDTO 中的字段仍然为空。
【解决方案2】:

我遇到了同样的问题。解决方案是使用 this answer 中建议的装饰器。按照您的代码,解决方案将类似于以下内容。

首先,我们必须在 Mapper 中指定装饰器:

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
@Primary
@DecoratedWith(FilesDTOMapperDecorator.class)
public interface FilesDTOMapper {
      // basic mapping here
      public FilesDTO map(BackHalfDomain domain);
}

然后,实现装饰器:

public abstract class FilesDTOMapperDecorator implements FilesDTOMapper {

    @Autowired
    @Qualifier("delegate")
    private FilesDTOMapper delegate;

    @Autowired
    private SomeRepository someRepository;

    @Override
    public FilesDTO map(BackHalfDomain domain) {
        // Delegate basic mapping
        FilesDTO filesDTO = delegate.map(domain);

        // Use the repository as needed to set additional mapping
        filesDTO.setSomeValue(repo.findById(id).getSomeValue());

        return filesDTO;
    }
}

【讨论】:

    猜你喜欢
    • 2023-01-15
    • 1970-01-01
    • 2017-11-03
    • 2019-05-05
    • 2020-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-29
    相关资源
    最近更新 更多