目录
1 错误现象
java服务在使用瀚高数据库(highgo)运行时,报错
Cause: com.highgo.jdbc.utl.PSOLException: 错误: 字段"hidden"的类型为 integer,但表达式的类型为 boolean
或者
Cause: com.highgo.jdbc.tiL.PSQLException: 错误: 字段“is_leaf" 的类型为 smallint,但表达式的类型为 boolean
。
2 问题原因
在java的实体类中字段为boolean
类型,但是瀚高数据库表中对应的字段类型为integer
或者smallint
。
由于项目主要使用MySQL
或者MariaDB
数据库,在创建boolean类型的字段时,会自动转化为tinyint(1)
,对应存储true/false
时,转化为1/0
。
在适配瀚高数据库时,由MySQL迁移的瀚高数据库中,相关表示boolean类型的字段tinyint(1)
被转化为smallint
,tinyint(4)
被转化为integer
。因此,在插入或者更新相关表记录时,会提示数据库字段类型不一致的问题。
3 解决方案
解决方案有两个,一个是将相关字段类型修改为boolean
,另一个是给瀚高数据库添加boolean
转化integer
或者smallint
类型的隐式转换规则。
由于修改字段类型本身工作量大,且初始化数据中相应字段的值也要跟着修改,处理较为麻烦,因此选择第二种方式,给瀚高数据库添加boolean
转化integer
或者smallint
类型的隐式转换规则。不需要对java代码和数据库迁移做任何其他处理,方便快捷。
瀚高数据库数据类型之间有3种转换,隐式转换,赋值转换,显式转换;对应的转换类型存在系统表 pg_cast中,三种方式分别对应 i(implicit),a(assignment),e(explicit)。
3.1 具体操作
3.1.1 查看当前数据库boolean类型的转换规则
可以看到,初始化数据库后,默认只有integer类型的显示转换。
select castsource::regtype,casttarget::regtype,castcontext,castfunc from pg_cast where castsource='boolean'::regtype;
3.1.2 修改integer类型的转换为隐式转换
update pg_cast set castcontext='i' where castsource = 'boolean'::regtype and casttarget='integer'::regtype;
3.1.3 添加boolean类型转换smallint类型的隐式转换
添加boolean类型转换smallint类型的自定义函数
create or replace function boolean2smallint(boolean) returns smallint as $$
begin
if $1 = true then
return 1;
else
return 0;
end if;
end;
$$ language plpgsql;
添加boolean类型转换smallint类型的隐式转换规则
create cast(boolean as smallint) with function boolean2smallint(boolean) as implicit;
修改完成后,再次查看当前数据库boolean类型的转换规则,可以看到,boolean
类型有了转换integer
和smallint
类型的隐式转换规则。
此时,相关表数据的操作恢复正常,存储true或false,自动转换为1或0,读取时自动转换为true或false。
注意!转换规则只对当前数据库生效,部署时,要针对现场数据库设置隐式转换规则。
3.1.4删除语句
如果创建错误,或者不需要相关转换规则,可以删除规则
drop cast(boolean as smallint);
drop function boolean2smallint;