Hibernate 6自定义方言实现按位与操作报错求助
解决Hibernate 6自定义方言中按位与函数注册错误的问题
问题背景
使用Hibernate 6自定义PostgreSQL方言,注册bitwise_and函数后,在HQL中调用该函数查询无读取权限的用户时,触发JDBC参数错误,生成的SQL结构异常。目标是执行等价于(permissions & 1) = 0的SQL查询(其中1代表READ权限标识)。
自定义方言代码:
public class CustomPostgreSQLDialect extends Dialect { @Override public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) { super.contributeTypes(typeContributions, serviceRegistry); } @Override public void initializeFunctionRegistry(FunctionContributions functionContributions) { super.initializeFunctionRegistry(functionContributions); functionContributions .getFunctionRegistry() .register("bitwise_and", new StandardSQLFunction("bitwise_and(?1 & ?2)", StandardBasicTypes.INTEGER)); } }
仓库查询方法:
public List<UserPermissions> getUsersWithoutReadPermissionCustomDialect() { return find("bitwise_and(permissions,1)=0").list(); }
触发的错误:
JDBC exception executing SQL [ select u1_0.id,u1_0.permissionValues,u1_0.permissions,u1_0.username from user_permissions u1_0 where bitwise_and(?1 & ?2)(u1_0.permissions,1)=0 ] [No value specified for parameter 1.]
错误原因
注册函数时,StandardSQLFunction的第一个参数被错误设置为bitwise_and(?1 & ?2),导致Hibernate解析时生成了异常的SQL结构:将?1 & ?2作为函数的一部分,同时把传入的permissions和1当成了额外的函数参数,最终引发参数未指定的错误。
解决方案
修改自定义方言中函数注册的SQL模板,直接映射为PostgreSQL的按位与运算符表达式?1 & ?2,正确关联HQL函数参数与SQL运算符:
public class CustomPostgreSQLDialect extends Dialect { @Override public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) { super.contributeTypes(typeContributions, serviceRegistry); } @Override public void initializeFunctionRegistry(FunctionContributions functionContributions) { super.initializeFunctionRegistry(functionContributions); // 正确映射bitwise_and为PostgreSQL按位与运算 functionContributions.getFunctionRegistry() .register("bitwise_and", new StandardSQLFunction("?1 & ?2", StandardBasicTypes.INTEGER)); } }
验证
修改后,HQL语句bitwise_and(permissions,1)=0会被正确解析为目标SQL:
select u1_0.id,u1_0.permissionValues,u1_0.permissions,u1_0.username from user_permissions u1_0 where (u1_0.permissions & 1)=0
此时可正常执行查询,返回无READ权限的用户列表。
内容的提问来源于stack exchange,提问作者vcoder
相关产品推荐
相关产品推荐

