Oracle获取List<Map>类型数据,使用jackson或者fastjson转换都会报错

本文介绍在多数据源环境下,使用Oracle数据库时遇到的Blob类型字段和Timestamp类型字段在转换为JSON时出现的异常问题。通过调整SQL查询语句,对Blob字段进行裁剪并转换为字符串类型,对Timestamp字段进行日期格式转换,最终解决了异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目场景:

最近在做多数据源相关产品,在测试使用mysql的时候是没有任何问题的,但是当使用oracle的时候问题就出来了,,,


问题描述

当我从service层取得List<Map>数据返回给controller的时候,mysql是没有问题的,会正常转换json对象,但是当使用oracle查询数据返回的时候抛异常了!!!而且有两个异常~~因为是多数据源,所以根本没法确定要映射的实体类,所以没有办法使用@JSONIGNORE注解

异常1:com.fasterxml.jackson.databind.JsonMappingException: "Direct self-reference leading to cycle (through reference chain: java.util.HashMap["options"]->java.util.HashMap["JSKH006_N"]->com.alibaba.druid.proxy.jdbc.ClobProxyImpl["connectionWrapper"]->com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl["DATA_"]->oracle.jdbc.driver.OracleDatabaseMetaData["DATA_"]->oracle.jdbc.driver.T4CConnection["wrapper"]
异常2: com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.xinping.crm.platform.mybatis.DatatablesPage["data"]->java.util.ArrayList[0]->java.util.HashMap["CREATE_TIME_"]->oracle.sql.TIMESTAMP["stream"])
@ApiOperation("预览数据视图")
@GetMapping("dataview/preview")
public AjaxResult preview(PreviewDataViewQuery query) {
   return AjaxResult.data(dataviewReportBuilder.previewReportDataview(query));
}

public List<Map<String, Object>> previewReportDataview(PreviewDataViewQuery query) {
   ReportDvDataview dataview = this.dataviewService.findById(query.getDatasourceId());
   DataviewConfig dvCfg = JSON.parseObject(dataview.getConfig(), DataviewConfig.class);
   genPreviewSql(dataview, dvCfg);
   String sql = dataview.getSqlPreview();
   List<Map<String,Object>> dataList=DvReportHelper.getPreviewData(dataview.getDatasourceId(), sql, query.getPageSize());
   return dataList;
}


原因分析及解决:

       上网查找了一下相关问题,有个博主说可以先使用fastjson进行转换,然后就不会出问题了,我试了下发现,还是不行,也会抛出fastjson的异常!!!简直了,人都要崩溃了。

        这时候就只能从sql语句上去做文章了。

       之后我一个一个字段去测试,发现oracle中有一个blob类型的字段,这个大字段存储大文件,原来第一个异常就是因为这个类型json转换不出来,会曝自引用的异常。后来只能给要查找的字段就行裁剪并转换成string类型,对字段进行裁剪使用dbms_lob.substr(字段名,裁剪大小,裁剪初始值),这个方法有个问题就是能裁剪的大小有上限,不过目前也能用。

之后使用UTL_RAW.CAST_TO_VARCHAR2()转成字符串,注意一定要给转换后的字段起别名,不然的话最后映射出来的数据,会是每个函数都是一个对象,对象里面加对象。例子如下:

return "UTL_RAW.CAST_TO_VARCHAR2(dbms_lob.substr(" + field.getField() + ",1000,1)) as " + field.getField();

        第二个异常就比较简单了,Jackson不是转换 oracle 的TimeStamp类型,这个时候就需要我们把这个类型的字段进行转换,可以转换成String类型to_char(),也可以转换为date类型to_date(),例子如下:

return "to_date(to_char(\"" + field.getField() + "\",'yyyy-mm-dd hh24:mi:ss'),'yyyy-mm-dd hh24:mi:ss') as " + field.getField();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值