You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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并不会返回你期望的totalline_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

火山引擎 最新活动