You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 19:22:01