使用Lombok的Spring项目Maven打包报Cannot find symbol异常求助
问题背景
在Spring Boot项目中搭配Lombok使用时,VS Code的Java扩展包会自动生成JPA静态元模型类(比如Setting_),本地运行完全正常,但执行./mvnw clean package时会抛出cannot find symbol错误,提示找不到com.myproject.base.data.model.entity.Setting_类。原因是Maven编译阶段未触发JPA元模型的生成逻辑,仅IDE生成的临时文件不会参与Maven的打包流程。
解决方案
需要在pom.xml中配置Maven注解处理器,让Hibernate的JPAMetaModelEntityProcessor在编译时自动生成元模型类,同时确保Lombok的注解处理器优先执行,避免元模型生成不完整。
1. 调整依赖配置
将hibernate-jpamodelgen的依赖范围改为provided(仅编译阶段需要,无需打包到最终产物),并移除手动指定的版本,使用Spring Boot Parent管理的版本,避免版本冲突:
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-jpamodelgen</artifactId> <scope>provided</scope> </dependency>
2. 配置Maven编译插件
添加maven-compiler-plugin,明确注解处理器的执行顺序:先运行Lombok处理器,再执行Hibernate元模型生成器,同时确保编译参数适配Jakarta注解:
<build> <plugins> <!-- 保留原Spring Boot Maven插件配置 --> <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>3.13.0</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> <annotationProcessorPaths> <!-- Lombok处理器优先执行,确保实体类代码完整 --> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.34</version> </path> <!-- Hibernate元模型生成器 --> <path> <groupId>org.hibernate</groupId> <artifactId>hibernate-jpamodelgen</artifactId> <scope>provided</scope> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build>
3. 验证生成结果
执行以下命令触发编译,检查元模型类是否生成:
./mvnw clean compile
编译完成后,可在target/generated-sources/annotations目录下找到自动生成的Setting_.java文件,此时再执行./mvnw clean package即可正常完成打包。
关键说明
- 注解处理器顺序不可颠倒:Lombok需要先处理实体类的
@Data等注解,生成完整的getter/setter代码,Hibernate元模型生成器才能正确识别实体类字段。 - 依赖版本由Spring Boot Parent管理,可避免Hibernate与Spring Boot的版本兼容性问题。
target/generated-sources/annotations是Maven默认的注解处理器生成目录,会被自动识别为源码目录,无需额外配置。
内容的提问来源于stack exchange,提问作者Socrates

