Spring Boot 3集成JPAStreamer失败,求解决方法或替代库
基于Spring Boot 3.0.2的项目包含大量查询及关联语句,尝试使用JPAStreamer库时遇到兼容性问题:该库在Spring Boot 2.x环境可正常运行,但Spring Boot 3.x环境下启动时无JPAStreamer横幅,target目录未生成元模型类(如Employee$),最终导致Spring无法找到依赖JPAStreamer的EmployeeService Bean,启动报错。
代码示例
private JPAStreamer jpaStreamer; public List<Employee> getEmployees(int offset,int limit){ return jpaStreamer.stream(Employee.class) .sorted(Employee$.name) .skip(offset) .limit(limit) .collect(Collectors.toList()); }
启动报错日志
2023-03-28T00:07:59.968+03:00 WARN 19084 --- [ main] ConfigServletWebServerApplicationContext : 上下文初始化期间遇到异常 - 取消刷新尝试: org.springframework.beans.factory.UnsatisfiedDependencyException: 创建名为'employeeController'的Bean时出错: 通过字段'service'表达的依赖项不满足: 找不到类型为'com.javatechie.jpastreamer.service.EmployeeService'的合格Bean: 期望至少有1个符合自动注入候选条件的Bean。依赖项注解: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 2023-03-28T00:07:59.970+03:00 INFO 19084 --- [ main] j.LocalContainerEntityManagerFactoryBean : 关闭持久化单元'default'的JPA EntityManagerFactory 2023-03-28T00:07:59.982+03:00 INFO 19084 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - 开始关闭... 2023-03-28T00:08:00.048+03:00 INFO 19084 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - 关闭完成。 2023-03-28T00:08:00.062+03:00 INFO 19084 --- [ main] o.apache.catalina.core.StandardService : 停止服务[Tomcat] 2023-03-28T00:08:00.189+03:00 INFO 19084 --- [ main] .s.b.a.l.ConditionEvaluationReportLogger : ApplicationContext启动失败。要显示条件评估报告,请启用'debug'参数重新运行应用。 2023-03-28T00:08:00.381+03:00 ERROR 19084 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : --- 应用启动失败 --- 描述: com.javatechie.jpastreamer.controller.EmployeeController中的字段service需要一个类型为'com.javatechie.jpastreamer.service.EmployeeService'的Bean,但未找到。 注入点具有以下注解: - @org.springframework.beans.factory.annotation.Autowired(required=true) 操作建议: 考虑在配置中定义一个类型为'com.javatechie.jpastreamer.service.EmployeeService'的Bean。 进程退出码1
方案1:升级JPAStreamer至Spring Boot 3兼容版本
JPAStreamer从1.1.0版本开始支持Jakarta EE(Spring Boot 3的底层依赖),此前版本仅支持Java EE(对应Spring Boot 2.x)。需更新依赖及注解处理器版本:
Maven配置
<!-- 核心依赖 --> <dependency> <groupId>com.speedment.jpastreamer</groupId> <artifactId>jpastreamer-core</artifactId> <version>1.2.3</version> <!-- 推荐使用最新稳定版 --> </dependency> <!-- 注解处理器,用于生成元模型类 --> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <annotationProcessorPaths> <path> <groupId>com.speedment.jpastreamer</groupId> <artifactId>jpastreamer-processor</artifactId> <version>1.2.3</version> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build>
Gradle配置
implementation 'com.speedment.jpastreamer:jpastreamer-core:1.2.3' annotationProcessor 'com.speedment.jpastreamer:jpastreamer-processor:1.2.3'
更新后重新编译项目,target目录会生成Employee$等元模型类,启动时会显示JPAStreamer横幅,Spring可自动识别并管理JPAStreamer Bean,依赖它的EmployeeService也能正常实例化。
方案2:手动配置JPAStreamer Bean
若升级版本后仍存在问题,可手动创建JPAStreamer的Spring Bean,确保Spring能正确管理:
import com.speedment.jpastreamer.core.JPAStreamer; import com.speedment.jpastreamer.core.JPAStreamerFactory; import jakarta.persistence.EntityManagerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class JPAStreamerConfig { @Bean public JPAStreamer jpaStreamer(EntityManagerFactory entityManagerFactory) { return JPAStreamerFactory.createJPAStreamerBuilder(entityManagerFactory) .build(); } }
此配置通过注入Spring管理的EntityManagerFactory构建JPAStreamer,确保其被Spring容器识别,解决依赖注入问题。
若不想使用JPAStreamer,以下是兼容Spring Boot 3的便捷查询库:
1. Querydsl JPA
提供类型安全的查询DSL,支持流式操作和复杂查询,与JPAStreamer使用方式类似。
依赖配置(Maven)
<dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-jpa</artifactId> <version>5.0.0</version> <!-- 兼容Jakarta EE --> </dependency> <dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-apt</artifactId> <version>5.0.0</version> <scope>provided</scope> </dependency>
示例代码
import com.querydsl.jpa.impl.JPAQueryFactory; import org.springframework.stereotype.Service; import java.util.List; import static com.javatechie.jpastreamer.model.QEmployee.employee; @Service public class EmployeeService { private final JPAQueryFactory queryFactory; public EmployeeService(JPAQueryFactory queryFactory) { this.queryFactory = queryFactory; } public List<Employee> getEmployees(int offset, int limit) { return queryFactory.selectFrom(employee) .orderBy(employee.name.asc()) .offset(offset) .limit(limit) .fetch(); } }
2. Spring Data JPA Specifications
Spring官方提供的类型安全查询方案,无需额外依赖,通过Specification接口构建查询条件,支持分页、排序。
示例代码
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.stereotype.Service; import java.util.List; @Service public class EmployeeService { private final EmployeeRepository employeeRepository; public EmployeeService(EmployeeRepository employeeRepository) { this.employeeRepository = employeeRepository; } public List<Employee> getEmployees(int offset, int limit) { // 可添加自定义查询条件,此处为示例默认空条件 Specification<Employee> spec = Specification.where(null); return employeeRepository.findAll(spec, org.springframework.data.domain.PageRequest.of(offset/limit, limit)) .getContent(); } } // 仓库接口需继承JpaSpecificationExecutor public interface EmployeeRepository extends JpaRepository<Employee, Long>, JpaSpecificationExecutor<Employee> {}
3. Blaze-Persistence
支持高级SQL特性(如CTE、窗口函数、递归查询),提供类型安全的DSL,兼容Spring Boot 3。
内容的提问来源于stack exchange,提问作者Mustafa zuhair

