Spring Boot集成Hibernate调用PostgreSQL函数报错:No Dialect mapping for JDBC type: 1111
解决PostgreSQL表函数在Spring Boot中映射JDBC类型1111的问题
这个错误的核心原因是你调用表函数的方式不对,导致PostgreSQL返回了Hibernate无法识别的复合类型结果。
问题分析
当你执行SELECT public.sp_number_of_trips_by_lines();时,PostgreSQL并不会返回你期望的total和line_id两列数据,而是返回一行包含复合类型的单列结果。这个复合类型没有对应的Hibernate方言映射,所以抛出了No Dialect mapping for JDBC type: 1111错误。而当函数仅返回单列时,查询返回的是普通标量值,Hibernate能正常识别类型,所以不会报错。
解决方案
1. 修正SQL查询语句
你需要把表函数当成表来查询,用SELECT * FROM的方式展开结果:
SELECT * FROM public.sp_number_of_trips_by_lines();
这样PostgreSQL会返回标准的两列多行结果,Hibernate就能正确映射了。
2. 修改Spring Boot控制器代码
更新你的原生查询语句,同时推荐用DTO来封装结果,让返回结构更清晰:
首先创建一个DTO类:
public class TripCountByLine { private Long total; private String lineId; // 必须提供与查询列顺序匹配的构造函数 public TripCountByLine(Long total, String lineId) { this.total = total; this.lineId = lineId; } // Getter方法 public Long getTotal() { return total; } public String getLineId() { return lineId; } }
然后修改控制器方法:
@GetMapping("trips-by-line") List<TripCountByLine> getSpNumberOfTripsByLine() { try { return entityManager .createNativeQuery( "SELECT * FROM public.sp_number_of_trips_by_lines()", TripCountByLine.class ) .getResultList(); } catch (Exception e) { e.printStackTrace(); // 建议使用SLF4J等日志框架替代System.out return new ArrayList<>(); } }
如果你暂时不想用DTO,也可以直接返回List<Object[]>,只要把SQL改成SELECT * FROM...,每个Object[]会包含两个元素:第一个是total(Long类型),第二个是lineId(String类型)。
额外提示
- 避免直接返回无泛型的
List,这样会丢失类型信息,不利于后续处理。 - 生产环境中不要用
System.out.println打印异常,改用专业的日志框架(如Logback、Log4j2)记录错误信息。
内容的提问来源于stack exchange,提问作者Luis Neves




