MapStruct生成的映射器未映射属性问题排查求助
MapStruct映射器无属性映射问题排查与解决
问题现象
MapStruct映射器已生成实现类,但方法体内仅执行无参构造并返回实例,未包含Lombok生成的getter/setter调用。Maven命令行编译时生成的实现正常,但IntelliJ IDEA环境下生成的代码不符合预期,导致属性映射失败(测试中name属性为null)。
最小复现代码
实体类 Cat
package com.example.demo.data; import lombok.Getter; import lombok.Setter; @Getter @Setter public class Cat { private String name; }
DTO类 CatDto
package com.example.demo.data; import lombok.Getter; import lombok.Setter; @Getter @Setter public class CatDto { private String name; }
映射器接口 CatMapper
package com.example.demo.mapper; import com.example.demo.data.Cat; import com.example.demo.data.CatDto; import org.mapstruct.Mapper; @Mapper(componentModel = "spring") public interface CatMapper { Cat toCat(CatDto cat); }
Maven配置 pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.3.5</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for MapStruct</description> <properties> <java.version>17</java.version> <mapstruct.version>1.6.3</mapstruct.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <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.projectlombok</groupId> <artifactId>lombok-mapstruct-binding</artifactId> <version>0.2.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <annotationProcessorPaths> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${mapstruct.version}</version> </path> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </path> </annotationProcessorPaths> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
测试代码
package com.example.demo; import com.example.demo.data.Cat; import com.example.demo.data.CatDto; import com.example.demo.mapper.CatMapper; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import static org.junit.jupiter.api.Assertions.assertEquals; @SpringBootTest class DemoApplicationTests { @Autowired private CatMapper catMapper; @Test void contextLoads() { CatDto catDto = new CatDto(); catDto.setName("Kitty"); Cat cat = catMapper.toCat(catDto); assertEquals(catDto.getName(), cat.getName()); // 失败:预期"Kitty",实际为null } }
IntelliJ生成的异常实现类
package com.example.demo.mapper; import com.example.demo.data.Cat; import com.example.demo.data.CatDto; import javax.annotation.processing.Generated; import org.springframework.stereotype.Component; @Generated( value = "org.mapstruct.ap.MappingProcessor", date = "2024-11-14T19:21:15+0300", comments = "version: 1.6.3, compiler: javac, environment: Java 17.0.13 (Amazon.com Inc.)" ) @Component public class CatMapperImpl implements CatMapper { @Override public Cat toCat(CatDto cat) { if ( cat == null ) { return null; } Cat cat1 = new Cat(); return cat1; } @Override public CatDto toDto(Cat cat) { if ( cat == null ) { return null; } CatDto catDto = new CatDto(); return catDto; } }
问题原因推测
IntelliJ IDEA默认按注解处理器的groupId首字母排序执行,Lombok(groupId首字母P)晚于MapStruct(groupId首字母M)执行,导致MapStruct处理时Lombok尚未生成getter/setter,无法识别属性映射关系。
解决方案
调整IntelliJ注解处理器顺序
- 打开
File > Settings > Build, Execution, Deployment > Compiler > Annotation Processors - 勾选
Enable annotation processing - 在
Processor path列表中,将lombok处理器移到mapstruct-processor之前 - 点击
Apply后重新编译项目
- 打开
强制使用Maven编译流程
- 在IntelliJ中执行
Maven > Lifecycle > compile,而非IDE自带的编译按钮 - 可配置IDE默认使用Maven编译:
File > Settings > Build, Execution, Deployment > Build Tools > Maven > Runner,勾选Delegate IDE build/run actions to Maven
- 在IntelliJ中执行
内容的提问来源于stack exchange,提问作者Cagepi
相关产品推荐
相关产品推荐

