MapStruct 和龙目岛没有合作

正在使用的技术堆栈:

爪哇8 地图结构: 1.2.0. 最终版 龙目岛: 1.16.18 Lombok Plugin 已经安装好了

  • 最初,当我删除 getter 和 setter 并添加 @Getter@Setter注释时,我遇到了一些问题,mapstruct无法找到属性并说: Unknown property "id" in result type com.vg.once.dto.OneDto. Did you mean "null"?
  • 我了解到龙目岛1.16.14或更新版本以及 Mapstruct1.2.0。Beta1或更新的版本是兼容的,可以一起工作,但我的版本是新的,然后所需的问题仍然出现。
  • 我已经尝试过的另一个解决方案是运行龙目岛的 Delombok 插件,但同样的问题还是出现了。

下面是项目文件:

实体对象: 一杯,咖啡:

import lombok.Getter;
import lombok.Setter;


@Getter
@Setter
public class One {


private int id;
private Integer version;
private int projectId;
private String title;
private String code;
private int sortOrder;


}

DTO 对象: OneDTO.java:

import lombok.Getter;
import lombok.Setter;


@Getter
@Setter
public class OneDto {


private int id;
private Integer version;
private int projectId;
private String title;
private String code;
private int sortOrder;


}

映射器类别: OneMapper.java

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;


import com.vg.once.dto.OneDto;
import com.vg.once.entity.One;


@Mapper
public interface OneMapper {


@Mapping(target="id", source="one.id")
OneDto createOne (One one);


}

Pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">


<modelVersion>4.0.0</modelVersion>
<groupId>com.vg</groupId>
<artifactId>mapstruct</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Mapstruct-test</name>


<properties>
<java.version>1.8</java.version>
<org.mapstruct.version>1.2.0.Final</org.mapstruct.version>
<org.projectlombok.version>1.16.18</org.projectlombok.version>
</properties>


<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
</dependencies>


<build>
<plugins>
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.16.18.1</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
</execution>
</executions>
<configuration>
<sourceDirectory>src/main/java</sourceDirectory>
<addOutputDirectory>false</addOutputDirectory>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
<encoding>UTF-8</encoding>
<skip>false</skip>
<verbose>false</verbose>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>

Build Trace :

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Mapstruct-test 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- lombok-maven-plugin:1.16.18.1:delombok (default) @ mapstruct ---
[INFO] Delombok complete.
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mapstruct ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.6.1:compile (default-compile) @ mapstruct ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 5 source files to /home/vivekgupta/Documents/workspaces/mapstruct-test/mapstruct/target/classes
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /home/vivekgupta/Documents/workspaces/mapstruct-test/mapstruct/src/main/java/com/vg/once/mapper/OneMapper.java:[12,9] Unknown property "id" in result type com.vg.once.dto.OneDto. Did you mean "null"?
[INFO] 1 error
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.637 s
[INFO] Finished at: 2017-12-06T19:23:53+05:30
[INFO] Final Memory: 19M/235M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.6.1:compile (default-compile) on project mapstruct: Compilation failure
[ERROR] /home/vivekgupta/Documents/workspaces/mapstruct-test/mapstruct/src/main/java/com/vg/once/mapper/OneMapper.java:[12,9] Unknown property "id" in result type com.vg.once.dto.OneDto. Did you mean "null"?
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

请分享我如何使用龙目岛和 MapStruct 一起工作?

110462 次浏览

它之所以不能工作,是因为 Maven 只使用 MapStruct 处理器,而不是龙目岛处理器。annotationProcessorPaths告诉 maven 应该使用哪些处理器。

Delombok 没有任何作用,因为每个类最终只有2个文件,我认为 maven 编译器没有看到它们。

你有两个选择:

选项1: 在 annotationProcessorPaths中添加 Lombok 依赖项

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</path>
<!-- This is needed when using Lombok 1.18.16 and above -->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
<!-- Mapstruct should follow the lombok path(s) -->
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>

选择2:

mapstruct-processor依赖项添加到依赖项中并删除 annotationProcessorPaths。这样,maven 编译器将获取依赖项中的所有注释处理器。

我建议使用选项1,因为您可以确定在代码中没有使用一些 MapStruct传递依赖项和内部类。

编辑:

为了确保 IntelliJ 注释处理也能正常工作,由于 IDEA-150621的原因,您必须添加 mapstruct-processor作为 provided依赖项。IntelliJ 目前没有使用 Maven 的 annotationProcessorPaths来正确配置项目。

编辑2:

1.18.16添加有关龙目岛 lombok-mapstruct-binding的信息和评论。

如果有人正在寻找如何使用 Gradle 配置它,以防万一:

dependencies {


// Lombok
compileOnly 'org.projectlombok:lombok:1.18.2'
annotationProcessor 'org.projectlombok:lombok:1.18.2'


// MapStruct
compileOnly 'org.mapstruct:mapstruct-jdk8:1.2.0.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.2.0.Final'


}

我也有过类似的问题,结果我的 MapStruct 版本已经过时了!

我使用的是 MapStruct 版本1.1.0. Final,但是使用的是 对于龙目岛支持至少1.2.0,需要最终版本

如果有人还在寻找这个问题的答案,我在 JOOQ + MapStruct 集成中遇到过类似的问题。答案是路径的顺序很重要

  • IntellijIdeas 2020.2.3
  • 爪哇8
  • SpringFramework2.4.0

我的构建片段

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.lombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
<!-- This is needed when using Lombok 1.8.16 and above -->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${org.lombok-mapstruct-binding.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
</plugin>
</plugins>
</build>

对我来说,解决方法很简单。

处理器的顺序很重要。

在我的例子中,mapstruct 处理器是在 Lombok 处理器之前定义的。如果顺序错误的 mapstruct 不生成映射,那么只需创建 result 类的实例(我在生成的实现中看到过)。

我的插件配置顺序正确:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>15</source>
<target>15</target>
<compilerArgs>--enable-preview</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>

当然,您还需要添加依赖项:

<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
</dependencies>

我同意顺序确实发挥了它的作用,也当使用梯度。在我的例子中,当我在多模块设置中将 subprojects { ... dependencyManagement{}}添加到父 build.gradle时,它就失败了。

Mapstruct 只是返回一个空实例。最近,我将 Intellij 版本升级到了2020.3和 Spring boot 2.4.0,并且遇到了这种情况。

当我把春天的版本改成2.3.o 的时候。我可以看到在编译之后,mapstruct 正在正确地构建映射。

浏览 mapstruct 最近更新的帖子。.但这需要时间。.所以,现在,我从 maven 搬到了 Gradle 项目,一切都很顺利。.听起来很奇怪,但却是真的。

如果有人能够提出正确的问题和解决方案,我将不胜感激。

对于将 Intellij 升级到2020.3版本后出现的问题,下面的解决方案对我很有用。 使用 lombok 版本: 1.18.16,lombok-mapstruct-binding: 0.2.0

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</dependency>

在插件的注释处理部分更改 Lombok 和 mapstruct 插件路径的顺序:

<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>11</source>
<target>11</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>


</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>

在我的 Spring Boot Maven 项目中进行了多次尝试之后,以下方法最终奏效:

Xml 的配置:

  1. 属性部分:
    <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
<version.lombok>1.18.18</version.lombok>
<version.mapstruct>1.4.2.Final</version.mapstruct>
<version.mapstruct-lombok>0.2.0</version.mapstruct-lombok>
</properties>
  1. 依赖关系部分:
    <dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${version.lombok}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${version.mapstruct}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${version.mapstruct-lombok}</version>
</dependency>
  1. 构建插件部分:
    <build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>9</source>
<target>9</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${version.mapstruct}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${version.lombok}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${version.mapstruct-lombok}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>

希望这有所帮助,我的 mapper 以前没有映射字段值,但是现在这些是源和目标之间的 mapper + 每个元素的嵌套列表也与字段值一起被映射。

如果有人在使用最新的龙目岛和 Mapstruct 库版本 :-时正在阅读本文

如果你正在使用龙目岛1.18.16或更新版本,那么你还需要添加 lombok-mapstruct-binding,以使龙目岛和 MapStruct 协同工作。

Https://mapstruct.org/faq/#can-i-use-mapstruct-together-with-project-lombok

对于 Spring-Boot,从结果 jar 中排除处理代码的最简单配置是:

pom.xml

     <dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
....
</dependencies>
<build>
<plugins>
<!-- exclude from jar-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
</exclude>
<exclude>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
...
</plugins>
</build>

没有 lombok-mapstruct-binding它也能正常工作。
也许有人评论,它需要什么?

显然,在 Gradle 应该是这样加载多个注释处理器的

dependencies {
implementation "org.mapstruct:mapstruct:1.4.2.Final", "org.projectlombok:lombok:1.18.20"
annotationProcessor "org.mapstruct:mapstruct-processor:1.4.2.Final", "org.projectlombok:lombok:1.18.20", "org.projectlombok:lombok-mapstruct-binding:0.2.0"
}

我认为在 pom.xml 中声明版本的正确方法是为版本引用类似 这个的内容,而不是手动指定所有内容的版本。例如 maven-compiler-plugin.versionlombok.version已经存在于那里

物业大厦 -

<properties>
<java.version>11</java.version>
<mapstruct.version>1.4.2.Final</mapstruct.version>
<lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
</properties>

附件块 -

<dependencies>
<!-- ... -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>


<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>


<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>


<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${lombok-mapstruct-binding.version}</version>
</dependency>


<!-- ... -->
</dependencies>

积木-

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>


<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>


<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${lombok-mapstruct-binding.version}</version>
</path>


<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>

此外,还必须使用正确的版本。

参见 给你

对于使用 build gradle 的人来说,这是我成功创建的. gradle 文件

dependencies {


compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
implementation "org.projectlombok:lombok-mapstruct-binding:${gradleMapstructVersion}"


implementation "org.mapstruct:mapstruct:${mapstructVersion}"
annotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}"


}

事情是这样的,如上所述,我们必须使用 org.projectlombok:lombok-mapstruct-binding,以便与 Lombok 一起使用 mapstruct