使用JPASpecificationExecutor构建Spring Boot动态查询的错误解决
我需要基于多组合筛选条件查询数据表,所以用了JPASpecificationExecutor。在SearchController里通过@RequestBody接收查询请求,还写了SpecificationBuilder类来构建实体的Specification对象,但运行时抛出如下错误:
UnsatisfiedDependencyException: Error creating bean with name 'searchController': Unsatisfied dependency expressed through field 'searchService': Error creating bean with name 'searchService': Unsatisfied dependency expressed through field 'userRepository': Error creating bean with name 'userRepository' defined in com.sub.sublayer.repository.UserRepository defined in @EnableJpaRepositories declared on SublayerApplication: Failed to convert property value of type 'jdk.proxy4.$Proxy87 implementing org.hibernate.Session,org.springframework.orm.jpa.EntityManagerProxy' to required type 'javax.persistence.EntityManager' for property 'entityManager'; Cannot convert value of type 'jdk.proxy4.$Proxy87 implementing org.hibernate.Session,org.springframework.orm.jpa.EntityManagerProxy' to required type 'javax.persistence.EntityManager' for property 'entityManager': no matching editors or conversion strategy found
我的UserRepository代码如下:
@Repository public interface UserRepository extends JpaRepository<User, Long>,JpaSpecificationExecutor<User> { }
项目的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.0.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.sub</groupId> <artifactId>sublayer</artifactId> <version>0.0.1-SNAPSHOT</version> <name>sublayer</name> <description>subs downstream</description> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>6.1.7.Final</version> <type>pom</type> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.32</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>2.7.9</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>6.0.6</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> </dependencies> <build> <plugins> <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> </plugins> </build> </project>
这个错误的核心原因是依赖版本冲突+Jakarta EE与javax API不兼容:Spring Boot 3.x基于Jakarta EE 9,所有javax开头的API都换成了jakarta开头,同时手动指定的多个JPA相关依赖版本和Spring Boot父版本不匹配,导致EntityManager类型转换失败。
按以下步骤修复:
清理冲突依赖
- 删除手动添加的
spring-data-jpa、spring-orm、hibernate-core、javax.persistence-api依赖,Spring Boot的spring-boot-starter-data-jpa会自动管理这些依赖的兼容版本。 - 删掉重复的
spring-boot-starter-test依赖。
- 删除手动添加的
替换javax.persistence为jakarta.persistence
代码里所有用到javax.persistence的注解(比如@Entity、@Id),全部替换成jakarta.persistence下的对应类,Spring Boot 3不再支持javax.persistence API。修正后的pom.xml依赖部分
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.32</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> </dependencies>
- 验证Repository代码
你的UserRepository继承关系没问题,修复依赖后即可正常使用JPASpecificationExecutor的findAll(Specification)方法。
内容的提问来源于stack exchange,提问作者Vaibhav306

