Hibernate 5.6中向NamedNativeQuery传递String[]映射Postgres text[]报错
问题:Hibernate 5.6调用PostgreSQL数组参数函数报错
PostgreSQL函数签名:
CREATE OR REPLACE FUNCTION public.ums_rate_permissions_for_collection(user_roles_arr text[], profile_id bigint, collection_id bigint)
通过Hibernate 5.6的NamedNativeQuery调用该函数时,传递多元素String数组映射为PostgreSQL的text[]失败:
原生查询定义:
@NamedNativeQuery( name = "getUserRolesPermissionsForCollection", query = "SELECT * FROM ums_rate_permissions_for_collection(ARRAY[:profileList], :profileId, :collectionId)" )
DAO代码:
public UmsRolesNavigationPermissionVO getRolePermissionsForCollection(final List<String> userRoles, final Long profileId, final Long collectionId) { String[] param = userRoles.toArray(new String[0]); NativeQuery query = this.getSession() .getNamedNativeQuery("getUserRolesPermissionsForCollection") .setParameterList("profileList", param) .setParameter("profileId", profileId) .setParameter("collectionId", collectionId); List result = query.list(); }
现象:
- PostgreSQL控制台执行
SELECT * FROM ums_rate_permissions_for_collection(ARRAY['Sales User', 'Admin'], 141, 330)正常 - 参数数组仅含一个元素时调用正常
- 数组含2个及以上元素时,报错
函数ums_rate_permissions_for_collection(record[], bigint, bigint)不存在,说明Hibernate将参数转换为了record[]而非text[]
尝试过手动拼接PostgreSQL数组格式字符串,但导致函数内RETURN QUERY语法错误,问题未解决。
解决思路
1. 直接绑定数组参数并指定PostgreSQL类型
修改NamedNativeQuery的SQL写法,去掉ARRAY[]包裹,直接使用参数,同时在绑定参数时指定Hibernate的PostgresTextArrayType类型(需确保引入Hibernate的PostgreSQL方言支持):
修改后的NamedNativeQuery:
@NamedNativeQuery( name = "getUserRolesPermissionsForCollection", query = "SELECT * FROM ums_rate_permissions_for_collection(:profileList, :profileId, :collectionId)" )
修改后的DAO参数绑定:
import org.hibernate.type.PostgresTextArrayType; // ... NativeQuery query = this.getSession() .getNamedNativeQuery("getUserRolesPermissionsForCollection") .setParameter("profileList", param, PostgresTextArrayType.INSTANCE) .setParameter("profileId", profileId) .setParameter("collectionId", collectionId);
2. 使用方言的数组参数处理
确保Hibernate配置中指定了正确的PostgreSQL方言:
hibernate.dialect=org.hibernate.dialect.PostgreSQL10Dialect
绑定参数时直接传递List<String>而非数组,同时指定类型:
.setParameter("profileList", userRoles, PostgresTextArrayType.INSTANCE)
3. 禁止手动拼接数组字符串
手动拼接的字符串会被当作单个字符串参数传递,而非数组类型,这会导致PostgreSQL解析错误。务必使用Hibernate提供的数组参数绑定方式,不要自行处理数组格式。
4. 检查函数返回值映射
如果修改参数绑定后仍有RETURN QUERY错误,需确认函数内部的返回结果是否与UmsRolesNavigationPermissionVO的字段正确映射,或者在NamedNativeQuery中添加resultClass指定返回类型:
@NamedNativeQuery( name = "getUserRolesPermissionsForCollection", query = "SELECT * FROM ums_rate_permissions_for_collection(:profileList, :profileId, :collectionId)", resultClass = UmsRolesNavigationPermissionVO.class )
内容的提问来源于stack exchange,提问作者d00d
相关产品推荐
相关产品推荐

