Spring Boot JpaRepository使用PostgreSQL array_agg报JDBC 2003错误如何解决
报错原因
JDBC type 2003对应PostgreSQL的ARRAY数据类型,默认的Hibernate PostgreSQL方言未注册该类型与Java类型的映射关系,因此无法解析array_agg函数返回的数组结果。同时你当前的Repository返回值定义也存在问题:array_agg返回的是单行单列的数组,Object[]实际接收到的是结果集的行数组,需要取第一个元素才能拿到数组内容。
解决方案
以下三个方案可按需选择:
方案1:自定义Hibernate方言(最彻底,支持全场景PG数组映射)
- 新建自定义方言类,继承项目当前使用的PostgreSQL方言(示例用PostgreSQL10Dialect,可根据你使用的PG版本替换),注册ARRAY类型映射:
import org.hibernate.dialect.PostgreSQL10Dialect; import org.hibernate.type.descriptor.sql.ArrayTypeDescriptor; import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; import java.sql.Types; public class CustomPostgresDialect extends PostgreSQL10Dialect { @Override public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) { if (sqlTypeDescriptor.getSqlType() == Types.ARRAY) { return ArrayTypeDescriptor.INSTANCE; } return super.remapSqlTypeDescriptor(sqlTypeDescriptor); } }
- 在application配置文件中指定使用自定义方言:
yml格式配置示例:
spring: jpa: properties: hibernate: dialect: 你的自定义方言类全路径.CustomPostgresDialect
properties格式配置示例:
spring.jpa.properties.hibernate.dialect=com.xxx.config.CustomPostgresDialect
- 修改Repository方法返回值:
@Query(value = "SELECT array_agg(department) FROM boxinfo;", nativeQuery = true) String[] getDept();
调用后可直接拿到部门字符串数组,转List只需调用Arrays.asList(getDept())即可。
提示:如果使用Hibernate 6+版本,无需自定义方言,官方已默认支持PG数组类型映射,直接修改返回值为String[]即可使用
方案2:SQL层面转换(无需修改配置,轻量快捷)
使用PG内置array_to_string函数把数组转成指定分隔符拼接的字符串,Java层面再拆分得到列表:
Repository代码修改为:
@Query(value = "SELECT array_to_string(array_agg(department), ',') FROM boxinfo;", nativeQuery = true) String getDeptStr();
调用时拆分字符串:
String deptStr = postGroupRepository.getDeptStr(); List<String> deptList = Arrays.asList(deptStr.split(","));
注意:如果部门字段本身包含逗号,需要换成不会出现在字段值中的分隔符,例如||等特殊字符
方案3:手动转换PG数组对象(无需修改任何配置,适合临时使用)
直接接收PG原生Array对象,手动转换为Java数组:
Repository代码修改为:
@Query(value = "SELECT array_agg(department) FROM boxinfo;", nativeQuery = true) Object getDeptArray();
调用时转换:
import org.postgresql.util.PGarray; Object arrayObj = postGroupRepository.getDeptArray(); if (arrayObj instanceof PGarray) { PGarray pGarray = (PGarray) arrayObj; String[] deptArray = (String[]) pGarray.getArray(); List<String> deptList = Arrays.asList(deptArray); }
内容的提问来源于stack exchange,提问作者Ajith Deivam
相关产品推荐
相关产品推荐

