使用 DI 和 MapStruct 将实体映射到 DTO
Entity mapping to DTO with DI with MapStruct
我是 mapstruct 的新手,我正在使用 spring 作为 DI 我跟进有关 DI 容器第 4.2 节的 MapStruct 文档页面 我尝试将我的实体映射到 dto,如下所示:
@Mapper(componentModel = "spring")
public interface CustomerMapper {
@Mapping(source = "registered",target = "activeProfile")
CustomerDto customerToCustomerDto(Customer customer);
}
当我 运行 mvn install 我得到这个错误:
java:27: error: No property named "registered" exists in source parameter(s).
@Mapping(source = "registered",target = "activeProfile")
我的实体使用 lombok,我确定有注册字段
请帮忙
我从实体中删除了 lombok
并手动创建了 setters/getters 并且运行良好
问题是,Lombok 生成的属性对 JSR-269 注释处理器不可见。它使用内部 api 直接修改源元素,而不是从带注释的源文件生成新的工件因此,任何依赖 getter/setter 方法存在的注释处理器在获取时都不会在源代码中看到它们执行。 Javac 会将“原始”源代码传递给注释处理器(在我们的例子中是 Mapstruct),而 Lombok 不做任何修改。
目前,如何让它们并排工作的最干净的解决方案是将 Lombok 注释类型和映射器移动到 2 个单独的项目中。看到一个official example in Mapstruct repo。
您不必删除 Lombok。
您可以将其设置为在 MapStruct 之前工作,如 ahus1 此处所述
https://github.com/mapstruct/mapstruct/issues/510
<!-- first de-lombok the sources to make getters/setters visible for mapstruct,
but *DON'T'* add the output directory to the sources, as we will only need it for mapstruct processing -->
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>${org.projectlombok.maven.version}</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
<configuration>
<sourceDirectory>src/main/java</sourceDirectory>
<addOutputDirectory>false</addOutputDirectory>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!-- use the de-lomobok files to create the necessary mappers -->
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>2.2.4</version>
<configuration>
<defaultOutputDirectory>
${project.build.directory}/generated-sources/mapstruct
</defaultOutputDirectory>
<processors>
<processor>org.mapstruct.ap.MappingProcessor</processor>
</processors>
<sourceDirectory>
${project.build.directory}/delombok
</sourceDirectory>
</configuration>
<executions>
<execution>
<id>process</id>
<phase>generate-sources</phase>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- now take the original sources together with the created mappers to the compiler -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<annotationProcessors>
<annotationProcessor>lombok.launch.AnnotationProcessorHider$AnnotationProcessor</annotationProcessor>
</annotationProcessors>
</configuration>
</plugin>
我已经在 pom.xml
中使用 annotationProcessors 解决了这个问题
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<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>
您既不必从项目中删除 lombok,也不必弄乱 maven 编译器插件。在你的 pom.xml 中声明 mapstruck 依赖之前,你只需要声明 lombok 依赖。使用此命令,maven 能够在 mapstruct 引用 getter 和 setter 之前 de-lombok 您的 类。这可能是maven的依赖调解的一个特性。
Dependency mediation - this determines what version of a dependency
will be used when multiple versions of an artifact are encountered.
Currently, Maven 2.0 only supports using the "nearest definition"
which means that it will use the version of the closest dependency to
your project in the tree of dependencies. You can always guarantee a
version by declaring it explicitly in your project's POM. Note that if
two dependency versions are at the same depth in the dependency tree,
until Maven 2.0.8 it was not defined which one would win, but since
Maven 2.0.9 it's the order in the declaration that counts: the first
declaration wins.
我是 mapstruct 的新手,我正在使用 spring 作为 DI 我跟进有关 DI 容器第 4.2 节的 MapStruct 文档页面 我尝试将我的实体映射到 dto,如下所示:
@Mapper(componentModel = "spring")
public interface CustomerMapper {
@Mapping(source = "registered",target = "activeProfile")
CustomerDto customerToCustomerDto(Customer customer);
}
当我 运行 mvn install 我得到这个错误:
java:27: error: No property named "registered" exists in source parameter(s).
@Mapping(source = "registered",target = "activeProfile")
我的实体使用 lombok,我确定有注册字段
请帮忙
我从实体中删除了 lombok
并手动创建了 setters/getters 并且运行良好
问题是,Lombok 生成的属性对 JSR-269 注释处理器不可见。它使用内部 api 直接修改源元素,而不是从带注释的源文件生成新的工件因此,任何依赖 getter/setter 方法存在的注释处理器在获取时都不会在源代码中看到它们执行。 Javac 会将“原始”源代码传递给注释处理器(在我们的例子中是 Mapstruct),而 Lombok 不做任何修改。
目前,如何让它们并排工作的最干净的解决方案是将 Lombok 注释类型和映射器移动到 2 个单独的项目中。看到一个official example in Mapstruct repo。
您不必删除 Lombok。 您可以将其设置为在 MapStruct 之前工作,如 ahus1 此处所述 https://github.com/mapstruct/mapstruct/issues/510
<!-- first de-lombok the sources to make getters/setters visible for mapstruct,
but *DON'T'* add the output directory to the sources, as we will only need it for mapstruct processing -->
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>${org.projectlombok.maven.version}</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
<configuration>
<sourceDirectory>src/main/java</sourceDirectory>
<addOutputDirectory>false</addOutputDirectory>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!-- use the de-lomobok files to create the necessary mappers -->
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>2.2.4</version>
<configuration>
<defaultOutputDirectory>
${project.build.directory}/generated-sources/mapstruct
</defaultOutputDirectory>
<processors>
<processor>org.mapstruct.ap.MappingProcessor</processor>
</processors>
<sourceDirectory>
${project.build.directory}/delombok
</sourceDirectory>
</configuration>
<executions>
<execution>
<id>process</id>
<phase>generate-sources</phase>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- now take the original sources together with the created mappers to the compiler -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<annotationProcessors>
<annotationProcessor>lombok.launch.AnnotationProcessorHider$AnnotationProcessor</annotationProcessor>
</annotationProcessors>
</configuration>
</plugin>
我已经在 pom.xml
中使用 annotationProcessors 解决了这个问题 <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<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>
您既不必从项目中删除 lombok,也不必弄乱 maven 编译器插件。在你的 pom.xml 中声明 mapstruck 依赖之前,你只需要声明 lombok 依赖。使用此命令,maven 能够在 mapstruct 引用 getter 和 setter 之前 de-lombok 您的 类。这可能是maven的依赖调解的一个特性。
Dependency mediation - this determines what version of a dependency will be used when multiple versions of an artifact are encountered. Currently, Maven 2.0 only supports using the "nearest definition" which means that it will use the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that if two dependency versions are at the same depth in the dependency tree, until Maven 2.0.8 it was not defined which one would win, but since Maven 2.0.9 it's the order in the declaration that counts: the first declaration wins.