【问题标题】:MapStruct and Lombok not working togetherMapStruct 和 Lombok 不能一起工作
【发布时间】:2018-05-20 10:58:10
【问题描述】:

正在使用的技术堆栈:

Java 8 MapStruct:1.2.0.Final 龙目岛:1.16.18 IDE:IntelliJ - Lombok 插件已安装

  • 最初,当我删除 getter 和 setter 并添加 @Getter@Setter 注释时遇到问题,mapstruct 无法找到该属性并说:Unknown property "id" in result type com.vg.once.dto.OneDto. Did you mean "null"?
  • 我知道 Lombok 1.16.14 或更高版本与 MapStruct 1.2.0.Beta1 或更高版本兼容并且可以一起工作,但我的版本比预期的要新,问题仍然存在。
  • 我已经尝试过的另一个解决方案是运行 Lombok 的 Delombok 插件,但仍然出现了同样的问题。

以下是项目文件:

实体对象:One.java

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>

构建跟踪

[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

请分享我如何同时使用 Lombok 和 MapStruct 来完成这项工作?

【问题讨论】:

    标签: java maven lombok mapstruct intellij-lombok-plugin


    【解决方案1】:

    显然这就是你应该在 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"
    }
    

    【讨论】:

      【解决方案2】:

      对于 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 也可以正常工作。
      也许有人cets,它需要什么?

      【讨论】:

        【解决方案3】:

        如果有人在使用最新的 Lombok 和 Mapstruct 库版本时阅读此内容:-

        如果您使用的是 Lombok 1.18.16 或更高版本,则还需要添加 lombok-mapstruct-binding 以使 Lombok 和 MapStruct 一起工作。

        https://mapstruct.org/faq/#Can-I-use-MapStruct-together-with-Project-Lombok

        【讨论】:

          【解决方案4】:

          在我的 Spring Boot Maven 项目中多次尝试后,以下终于奏效了:

          pom.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>
          

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

          【讨论】:

          • 2021 年 12 月仍然有效,谢谢
          【解决方案5】:

          它不起作用的原因是因为 Maven 只使用 MapStruct 处理器而不是 Lombok 处理器。 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:

          添加 Lombok 1.18.16 所需的有关 lombok-mapstruct-binding 的信息和评论。

          【讨论】:

          • 我认为“lombok”应该先出现,然后是“mapstruct-processor”
          • 顺序不应该有区别。我们正在与 Lombok 团队明确合作
          • 我认为这些信息肯定需要添加到 mapstructs FAQ。他们的示例项目在没有在 mavens 构建部分中定义的注释处理器的情况下工作,但我认为他们可以在那里提到它(我花了一些时间在这里找到解决方案)。
          • 感谢您对 lombok-mapstruct-binding (mapstruct.org/faq/…) 的评论。可用版本:0.2.0。只有一件事&lt;!-- This is needed when using Lombok 1.8.16 and above --&gt; => &lt;!-- This is needed when using Lombok 1.18.16 and above --&gt;
          • 在 Mapstruct 处理器也为我工作之前添加 Lombok @DonSrinath
          【解决方案6】:

          对于将 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>
          

          【讨论】:

            【解决方案7】:

            mapstruct 只是返回一个空实例。最近我将Intellij版本升级到2020.3,spring boot 2.4.0,落到了这种情况。

            当我将 spring 版本更改为 2.3.o.RELEASE 时,编译后我可以看到 mapstruct 正在正确构建映射。

            浏览 mapstruct 最近更新的帖子.. 但这需要时间.. :) 所以,就目前而言,我从 maven 转移到 Gradle 项目,一切正常.. 听起来很奇怪但确实如此......

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

            【讨论】:

              【解决方案8】:

              我同意订单确实发挥了作用,在使用 gradle 时也是如此。在我的情况下,当我在多模块设置中将 subprojects { ... dependencyManagement{}} 添加到父 build.gradle 时,它就失败了。

              【讨论】:

                【解决方案9】:

                对我来说解决方案非常简单。

                处理器的顺序很重要。

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

                我的插件配置顺序正确:

                <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>
                

                【讨论】:

                  【解决方案10】:

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

                  • IntellijIdea 2020.2.3
                  • Java 8
                  • Spring 框架 2.4.0

                  我的构建 sn-p

                  <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>
                  

                  【讨论】:

                    【解决方案11】:

                    我也有类似的问题。原来我的 MapStruct 版本已经过时了!

                    我使用 MapStruct 版本 1.1.0.Final,但对于 Lombok 支持,至少需要 1.2.0.Final

                    【讨论】:

                      【解决方案12】:

                      以防万一有人正在寻找如何使用 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'
                      
                      }
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2023-04-10
                        • 1970-01-01
                        • 2020-02-07
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2014-01-07
                        • 2019-08-17
                        相关资源
                        最近更新 更多