programing

MapStruct와 Lombok이 함께 작동하지 않음

kingscode 2022. 10. 8. 17:21
반응형

MapStruct와 Lombok이 함께 작동하지 않음

사용 중인 기술 스택:

Java 8 MapStruct : 1.2.0.최종 Lombok: 1.16.18 IDE: IntelliJ - Lombok 플러그인이 이미 설치되어 있습니다.

  • 를 제거하고 getter setter를 추가했을 때 문제가 .@Getter ★★★★★★★★★★★★★★★★★」@Setter 석,,mapstructUnknown property "id" in result type com.vg.once.dto.OneDto. Did you mean "null"?
  • MapStruct 1.2.0과 함께 롬복 1.16.14 이후 버전을 알게 되었습니다.베타 1 이후는 호환성이 있어 함께 동작할 수 있지만, 사용하고 있는 버전은 원하는 버전보다 최신 버전입니다.
  • 제가 이미 시도했던 솔루션 중 하나는 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를 함께 사용하여 이 작업을 수행할 수 있는 방법을 공유해 주십시오.

동작하지 않는 이유는 MapStruct 프로세서만 사용하고 Lombok 프로세서는 사용하지 않기 때문입니다.annotationProcessorPaths는 어떤 프로세서를 사용해야 하는지를 나타냅니다.

delombok은 클래스당 2개의 파일로 끝나기 때문에 아무것도 하지 않으며, maven 컴파일러는 그것들을 볼 수 없다고 생각합니다.

넌 두가지 옵션이 있다 :

1: (1: 롬복 의존관계)annotationProcessorPaths

<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하여 "Dependency"를 합니다.annotationProcessorPaths이렇게 하면 maven 컴파일러는 사용자의 의존관계에 있는 주석 프로세서를 모두 선택합니다.

1을 것 .이 사용하고 알 수 있습니다.이것에 대해서는, 어느쪽인가를 사용하고 있지 않은 것을 확인할 수 있습니다.MapStruct트랜시티브 종속성 및 내부 클래스를 코드 내에 입력합니다.

편집:

IntelliJ 주석 처리를 .mapstruct-processorprovidedIDEA-150621에 의한 의존성.현재 IntelliJ는 다음 명령어를 사용하지 않습니다.annotationProcessorPaths메이븐

편집 2:

에 와 코멘트를 합니다.lombok-mapstruct-binding롬복 1.18.16

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 프로세서는 lombok 프로세서보다 먼저 정의되었습니다.잘못된 순서 맵 구조가 매핑을 생성하지 않는 경우 결과 클래스의 인스턴스를 생성하기만 하면 됩니다(생성된 구현에서 확인).

올바른 순서로 플러그인 구성:

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

Spring Boot Maven 프로젝트에서 여러 번 시도한 후 다음 작업이 성공적으로 수행되었습니다.

pom.xml 설정:

  1. Properties ]섹션:
    <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. [ Dependencies ]섹션:
    <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가 필드 값을 매핑하지 않았지만, 현재는 이러한 값이 소스와 타깃 사이의 매핑이며, 각 요소의 중첩 리스트도 필드 값과 함께 매핑됩니다.

저도 비슷한 문제가 있었어요.내 MapStruct 버전이 구식이었대!

MapStruct 버전 1.1.0을 사용했습니다.최종. 단, 롬복의 경우 1.2.0 이상 지원.기말고사는 필수입니다.

LombokMapstruct 라이브러리의 최신 버전을 사용할 때 이 문서를 읽는 사람이 있다면:

1. Lombok 1.18.16을 .lombok-mapstruct-binding롬복 맵스트럭트

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

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

그래들에서는 이렇게 여러 주석 프로세서를 로드해야 합니다.

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

아직 이 답을 찾는 사람이 있다면 JOOQ + MapStruct Integration에서도 비슷한 문제에 직면했습니다.정답은 경로의 순서입니다.

  • 인텔리아이디어 2020.2.3
  • 자바 8
  • 스프링 프레임워크 2.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>

지도 구조가 null 인스턴스를 반환하고 있습니다.최근 Intelij 버전을 2020.3, 스프링 부츠 2.4.0으로 업그레이드하여 이 상황에 빠졌습니다.

봄 버전을 2.3.o로 변경했을 때.릴리즈, 컴파일 후에 지도 구조가 적절하게 지도를 만들고 있다는 것을 알 수 있었습니다.

지도 구조가 최근에 업데이트된 게시물을 살펴보는 중..하지만 시간이 걸릴거야..그래서 지금은 maven에서 Gradle 프로젝트로 옮겼고, 모두 잘 되어가고 있습니다.이상하게 들리지만 사실이야

어떤 것이 정확히 옳은 문제이고 어떤 해결책이 있는지 게시해주시면 감사하겠습니다.

pom.xml에서 버전을 선언하는 올바른 방법은 모든 버전의 버전을 수동으로 지정하는 것이 아니라 이러한 버전을 참조하는 것입니다.maven-compiler-plugin.version,lombok.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>

그래들을 사용할 때도 순서가 제 역할을 한다는 것에 동의합니다.제 경우, 제가 추가하자마자 실패했습니다.subprojects { ... dependencyManagement{}}부모에게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롬복과 함께 지도 구조를 사용하기 위해

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동작도 양호합니다.
누가 뭐하러 하냐고?

또한 올바른 버전을 사용해야 합니다.

여기를 참조해 주세요.

언급URL : https://stackoverflow.com/questions/47676369/mapstruct-and-lombok-not-working-together

반응형