Spring 3.0.1迁移后Hibernate无法识别SqlResultSetMapping问题求助
迁移Spring 3.0.1后@SqlResultSetMapping映射找不到的排查与解决
核心原因分析
Spring Boot 3.0.x默认搭配Hibernate 6.x(Spring 2.7用的是Hibernate 5.6),两者在JPA注解规范、映射扫描逻辑上有显著差异,尤其是:
- 注解包从
javax.persistence迁移到jakarta.persistence @SqlResultSetMapping的扫描范围和定义位置要求更严格- 映射名称的大小写敏感性增强
排查与解决步骤
1. 检查JPA注解的包路径(最常见问题)
Spring 3.0基于Jakarta EE 9,所有JPA相关注解必须从javax.persistence替换为jakarta.persistence,否则Hibernate 6会完全忽略这些注解,导致映射无法被识别。
错误示例:
import javax.persistence.SqlResultSetMapping; // 旧包,Spring 3.0不兼容
正确示例:
import jakarta.persistence.SqlResultSetMapping; import jakarta.persistence.ColumnResult; import jakarta.persistence.ConstructorResult;
2. 确认@SqlResultSetMapping的定义位置与名称匹配
Hibernate 6不支持在Repository接口的@Query注解上直接定义@SqlResultSetMapping,必须将映射定义在实体类上或package-info.java全局映射文件中,且名称必须完全匹配(包括大小写)。
实体类上定义映射
@Entity @SqlResultSetMapping( name = "herculesforecast", // 必须与查询中引用的名称完全一致 classes = @ConstructorResult( targetClass = HerculesForecastDTO.class, columns = { @ColumnResult(name = "id", type = Long.class), @ColumnResult(name = "forecast_date", type = LocalDate.class) // 其他字段需与查询返回列名一一对应 } ) ) public class YourEntity { // 实体字段定义 }
全局映射(package-info.java)
如果需要全局复用映射,可在对应包下创建package-info.java:
@SqlResultSetMapping( name = "herculesforecast", classes = @ConstructorResult( targetClass = HerculesForecastDTO.class, columns = { @ColumnResult(name = "id", type = Long.class), @ColumnResult(name = "forecast_date", type = LocalDate.class) } ) ) package com.yourproject.mappings; import jakarta.persistence.ColumnResult; import jakarta.persistence.ConstructorResult; import jakarta.persistence.SqlResultSetMapping;
同时确保该包被Spring的实体扫描器覆盖。
3. 验证实体扫描范围
如果带有@SqlResultSetMapping的类不在Spring Boot主应用类的子包下,需通过@EntityScan显式指定扫描路径:
@SpringBootApplication @EntityScan(basePackages = {"com.yourproject.entity", "com.yourproject.mappings"}) public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } }
4. 检查原生查询的映射引用
确保Repository中的原生查询正确引用映射名称:
@Repository public interface ForecastRepository extends JpaRepository<YourEntity, Long> { @Query( value = "SELECT id, forecast_date FROM hercules_forecast WHERE ...", nativeQuery = true, resultSetMapping = "herculesforecast" // 这里必须与映射名称完全匹配 ) List<HerculesForecastDTO> getHerculesForecast(); }
5. 排查大小写敏感性
Hibernate 6对映射名称的大小写严格匹配,若你的映射名称是HerculesForecast而查询中写的是herculesforecast,会导致找不到映射,需统一大小写。
内容的提问来源于stack exchange,提问作者abhijit dash
相关产品推荐
相关产品推荐

