MapStruct属性映射失效求助:无法识别DTO属性
MapStruct 1.5.5.Final 属性完全不映射问题排查与解决
问题现象
在Spring Boot项目中使用MapStruct 1.5.5.Final进行对象映射时,出现以下异常情况:
- 定义的Mapper接口生成的实现类未执行任何属性映射,直接返回空的Builder实例
- 手动添加
@Mapping注解后,编译报错:No property named "name" exists in source parameter(s). Type "SignUpRequestDTO" has no properties.
相关代码
SignUpRequestDTO类
package ez.ndvz.application.api.v1.dto.authenticationDTOs; @Data @Builder public class SignUpRequestDTO { @NonNull @NotBlank String name; @NotBlank @NonNull String lastName; @NonNull @NotBlank @Pattern(regexp = "^\\+(389)\\s?([2-7]0|78|77|75|76|71|72|73|74)\\s?([0-9]{6})$", message = "Invalid phone number format for North Macedonia") String phoneNumber; @NotBlank @NonNull @Email String email; @NonNull @NotBlank @Size(min = 6) String password; }
User领域类
package ez.ndvz.core.domain.models; @AllArgsConstructor @Builder @Getter @Setter public class User { private Long id; private String name; private String lastName; private String phoneNumber; private String email; private String password; private Set<Roles> roles; private List<Property> propertyList; }
Mapper接口
package ez.ndvz.application.api.v1.mapper; @Mapper(componentModel = "spring") public interface UserHttpMapper { User toDomain(SignUpRequestDTO signUpRequestDTO); User toDomain(SignInRequestDTO signInRequestDTO); UserEntity toEntity(SignInRequestDTO signInRequestDTO); UserEntity toEntity(SignUpRequestDTO signUpRequestDTO); }
生成的实现类(无属性映射)
@Generated( value = "org.mapstruct.ap.MappingProcessor", date = "2024-02-14T11:32:45+0100", comments = "version: 1.5.5.Final, compiler: IncrementalProcessingEnvironment from gradle-language-java-8.2.jar, environment: Java 19.0.2 (Amazon.com Inc.)" ) @Component public class UserHttpMapperImpl implements UserHttpMapper { @Override public User toDomain(SignUpRequestDTO signUpRequestDTO) { if ( signUpRequestDTO == null ) { return null; } User.UserBuilder user = User.builder(); return user.build(); } @Override public User toDomain(SignInRequestDTO signInRequestDTO) { if ( signInRequestDTO == null ) { return null; } User.UserBuilder user = User.builder(); return user.build(); } @Override public UserEntity toEntity(SignInRequestDTO signInRequestDTO) { if ( signInRequestDTO == null ) { return null; } UserEntity.UserEntityBuilder userEntity = UserEntity.builder(); return userEntity.build(); } @Override public UserEntity toEntity(SignUpRequestDTO signUpRequestDTO) { if ( signUpRequestDTO == null ) { return null; } UserEntity.UserEntityBuilder userEntity = UserEntity.builder(); return userEntity.build(); } }
手动添加@Mapping后的报错信息
error: No property named "name" exists in source parameter(s). Type "SignUpRequestDTO" has no properties. User toDomain(SignUpRequestDTO signUpRequestDTO)
Gradle依赖配置
dependencies { implementation project(':domain') implementation project(':infrastructure:persistance') implementation project(':infrastructure:authentication') implementation 'org.mapstruct:mapstruct:1.5.5.Final' annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final' implementation 'jakarta.validation:jakarta.validation-api:3.0.2' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.projectlombok:lombok:1.18.28' annotationProcessor 'org.projectlombok:lombok:1.18.28' testImplementation 'org.springframework.boot:spring-boot-starter-test' }
问题原因
核心问题是Lombok与MapStruct的注解处理器执行顺序冲突:MapStruct注解处理器先于Lombok运行,此时Lombok尚未生成@Data、@Builder对应的getter/setter方法和Builder逻辑,导致MapStruct无法识别DTO和实体类中的属性,进而无法生成映射代码。
解决方案
通过添加lombok-mapstruct-binding依赖,强制Lombok先于MapStruct执行注解处理,确保MapStruct能识别到Lombok生成的属性。
修改后的Gradle依赖配置如下:
dependencies { implementation project(':domain') implementation project(':infrastructure:persistance') implementation project(':infrastructure:authentication') implementation 'org.mapstruct:mapstruct:1.5.5.Final' annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final' implementation 'jakarta.validation:jakarta.validation-api:3.0.2' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.projectlombok:lombok:1.18.28' annotationProcessor 'org.projectlombok:lombok:1.18.28' // 添加绑定依赖,确保Lombok优先处理 annotationProcessor 'org.projectlombok:lombok-mapstruct-binding:0.2.0' testImplementation 'org.springframework.boot:spring-boot-starter-test' }
验证效果
修改依赖后重新编译项目:
- MapStruct会自动识别同名属性并生成完整映射逻辑,无需手动添加
@Mapping注解 - 生成的实现类会正确调用Builder方法设置对应属性,示例如下:
@Override public User toDomain(SignUpRequestDTO signUpRequestDTO) { if ( signUpRequestDTO == null ) { return null; } User.UserBuilder user = User.builder(); user.name( signUpRequestDTO.getName() ); user.lastName( signUpRequestDTO.getLastName() ); user.phoneNumber( signUpRequestDTO.getPhoneNumber() ); user.email( signUpRequestDTO.getEmail() ); user.password( signUpRequestDTO.getPassword() ); return user.build(); }
内容的提问来源于stack exchange,提问作者Nisi Zenuni
相关产品推荐
相关产品推荐

