Spring Boot 3升级后带List参数的JPA查询偶发异常问题
Spring Boot 3升级后JPA查询偶发类型转换异常问题
问题背景
升级至最新Spring Boot 3版本后,JPA查询在传入单个元素的accountNames列表时,会以约1/5的概率抛出类型转换异常,回退到Spring Boot 2.7.X版本则问题消失。
Account实体类定义
@Entity @Data @Builder @AllArgsConstructor @NoArgsConstructor public class Account { @Id @GeneratedValue @JsonIgnore private Long id; private String accountName; private String supplierName; private String customerName; private Double amount; }
JPA仓库接口及查询逻辑
@RepositoryRestResource public interface AccountRestResource extends PagingAndSortingRepository<Account, Long>, CrudRepository<Account, Long> { @Query("SELECT DISTINCT account.customerName " + "FROM Account account " + "WHERE UPPER(account.customerName) LIKE CONCAT('%',UPPER(:filter),'%') " + "AND ((:accountNames) IS NULL OR account.accountName IN (:accountNames)) " + "ORDER BY account.customerName") Page<String> findDistinctCustomerNames(List<String> accountNames, String filter, Pageable page); }
抛出的异常信息
org.springframework.orm.jpa.JpaSystemException: Unknown wrap conversion requested: java.util.ArrayList to java.lang.String :
org.hibernate.type.descriptor.java.StringJavaType(java.lang.String)
项目依赖配置
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-rest</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>jakarta.inject</groupId> <artifactId>jakarta.inject-api</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!-- Test--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>test</scope> </dependency> </dependencies>
问题触发条件
- 当
accountNames为null时,查询正常执行 - 当
accountNames仅包含单个元素时,偶发触发类型转换异常
修复方案
该问题是Spring Boot 3配套的Hibernate 6.x版本在处理单元素列表参数时的类型推断bug,可通过以下方式修复:
- 优化JPQL查询逻辑
将原查询中的(:accountNames) IS NULL替换为结合空列表判断的逻辑,同时显式指定参数注解,避免Hibernate误判参数类型:
@Query("SELECT DISTINCT account.customerName " + "FROM Account account " + "WHERE UPPER(account.customerName) LIKE CONCAT('%',UPPER(:filter),'%') " + "AND (:accountNames IS NULL OR :accountNames IS EMPTY OR account.accountName IN (:accountNames)) " + "ORDER BY account.customerName") Page<String> findDistinctCustomerNames(@Param("accountNames") List<String> accountNames, @Param("filter") String filter, Pageable page);
- 升级Hibernate版本
查看Hibernate官方修复记录,升级到包含该bug修复的版本(Spring Boot 3的后续小版本可能已集成对应修复)。
内容的提问来源于stack exchange,提问作者JVDD
相关产品推荐
相关产品推荐

