
该错误源于 JPA 原生查询返回的列与实体类字段不匹配:当 SQL 仅返回 COUNT(...) 单一数值时,却声明返回 List 实体列表,导致 Hibernate 尝试按实体映射所有字段(如 l_p),但结果集中根本不存在该列。
该错误源于 jpa 原生查询返回的列与实体类字段不匹配:当 sql 仅返回 count(...) 单一数值时,却声明返回 list<character></character> 实体列表,导致 hibernate 尝试按实体映射所有字段(如 l_p),但结果集中根本不存在该列。
在 Spring Boot + JPA(Hibernate)+ PostgreSQL 的组合中,The column name l_p was not found in this ResultSet 是一个典型且易被忽视的类型契约失配问题。其本质并非数据库连接或字段注解错误,而是查询结果结构与方法返回类型语义严重不一致。
? 错误根因分析
您定义的原生查询:
@Query(
value = "SELECT COUNT(marvel_comic_character_name) " +
"FROM marvel_super_heroes WHERE marvel_comic_character_name ~* ':character'",
nativeQuery = true)
List<Character> countAllCharacterOccurences(@Param("character") String character);执行后,PostgreSQL 仅返回 单个整型列(例如列名为 count),而方法签名却要求将结果映射为 List<character></character> —— 即 Hibernate 会尝试用 ResultSet 中的每一行去构造完整的 Character 实体对象。由于实体类首字段 l_p 对应数据库列 l_p,但结果集根本没有该列,因此抛出 Unable to find column position by name: l_p。
⚠️ 注意:即使您在实体中使用了 @Column(name = "l_p"),此注解只影响 JPA 管理的表映射,对 nativeQuery = true 的原生查询无约束力;原生查询的结果列名完全取决于 SQL 中的 SELECT 表达式(此处是默认别名 count)。
✅ 正确解决方案
根据实际业务需求,选择以下任一方式修复:
✅ 方案一:返回标量值(推荐用于计数场景)
@Query(
value = "SELECT COUNT(marvel_comic_character_name) " +
"FROM marvel_super_heroes WHERE marvel_comic_character_name ~* :character",
nativeQuery = true)
Long countAllCharacterOccurences(@Param("character") String character);- 返回类型改为
Long(或int/Integer),直接接收聚合结果; - 移除
:character中多余的单引号(JPA 参数绑定自动处理字符串转义,加引号会导致 SQL 语法错误); - 方法名建议同步更新为
count...以体现语义(如countCharacterOccurrences)。
✅ 方案二:若需返回实体列表,请改写为实体查询(非原生)
// 使用 JPQL(自动映射实体,无需列名匹配)
@Query("SELECT c FROM Character c WHERE LOWER(c.marvelComicCharacterName) LIKE LOWER(CONCAT('%', :character, '%'))")
List<Character> findCharactersByPartialName(@Param("character") String character);✅ 优势:类型安全、支持懒加载、自动处理列映射;
❌ 不适用:正则匹配~*在 JPQL 中不可用(需改用LIKE或保留原生查询但放弃实体映射)。
✅ 方案三:原生查询 + 手动字段映射(高级用法)
若必须用原生 SQL 且需部分字段,可返回 Object[] 或自定义 DTO:
// 定义轻量 DTO(无 JPA 注解)
public record CharacterCount(Long count) {}
@Query(
value = "SELECT COUNT(marvel_comic_character_name) AS count " +
"FROM marvel_super_heroes WHERE marvel_comic_character_name ~* :character",
nativeQuery = true)
CharacterCount countCharacterOccurrences(@Param("character") String character);✅ 关键:SQL 中显式使用
AS count别名,并确保 DTO 字段名与别名一致(或使用@SqlResultSetMapping)。
? 重要注意事项
-
永远避免
nativeQuery = true+ 实体返回类型,除非SELECT *且列名/顺序与实体完全一致; - PostgreSQL 的正则操作符
~*区分大小写不敏感,但参数值本身无需额外包裹单引号(JPA 会自动注入); - 测试时可通过开启 SQL 日志验证实际执行语句:
# application.yml spring: jpa: show-sql: true properties: hibernate: format_sql: true logging: level: org.hibernate.SQL: DEBUG org.hibernate.type.descriptor.sql.BasicBinder: TRACE
通过精准匹配查询意图与 Java 类型契约,即可彻底规避此类 ResultSet 列名异常。核心原则始终是:让代码说真话——返回什么,就声明什么。


















