(OracleConnection) conn 强转失败是因为 HikariCP 返回的是代理类 HikariProxyConnection,非原始 oracle.jdbc.OracleConnection;正确做法是调用 conn.unwrap(OracleConnection.class) 获取底层连接。
oracle 本身不直接存储 java 对象,而是通过 jdbc 将 java 类型映射为 oracle 自定义类型(object / varray / table)来实现“类对象语义”的传递与持久化。关键不是“存 java 对象”,而是让 java 知道怎么把数据塞进 oracle 的结构里、再怎么取出来。
为什么 (OracleConnection) conn 会 ClassCastException?
HikariCP 返回的是代理连接 HikariProxyConnection,不是原始的 oracle.jdbc.OracleConnection。直接强转必然失败。
- 必须用
unwrap()获取底层连接:conn.unwrap(OracleConnection.class) - 若使用较新版本 Oracle JDBC(21c+),推荐用标准 JDBC 接口
createStruct()/createArray(),避免依赖 Oracle 特有类 - 旧代码中
connection.createARRAY(...)必须基于OracleConnection实例,否则抛ClassCastException
Java 如何映射 Oracle OBJECT 类型?
核心是实现 SQLData 接口,并注册到 Connection 的 TypeMap 中。Oracle 靠这个知道“收到 T_NAPRAVI_NALOG_TEST 时该实例化哪个 Java 类”。
-
SQLData.readSQL()控制从数据库读字段的顺序和类型(注意:必须严格匹配 Oracle 类型定义字段顺序) -
SQLData.writeSQL()控制写入时字段顺序,不能漏、不能错位 - TypeMap 注册必须在
CallableStatement执行前完成:conn.getTypeMap().put("sepadd.T_NAPRAVI_NALOG_TEST", TNapraviNalog.class) - 包名大小写敏感 —— Oracle 类型名是
"SEPADD"."T_NAPRAVI_NALOG_TEST",TypeMap key 就得是"sepadd.T_NAPRAVI_NALOG_TEST"(小写 schema 名)
传 VARRAY 或 TABLE 类型时数组维度怎么处理?
Java 侧用二维数组(Object[][])对应 Oracle 的 TABLE OF OBJECT;一维数组(String[] / BigDecimal[])对应 VARRAY。但容易踩的坑很多:
-
createARRAY("T_UPLOAD_FILE_TABLE", uploads)中uploads是Object[][],每行是一个Object[4],且每个元素类型必须和 OracleOBJECT字段一一匹配(比如第 0 位是VARCHAR2,Java 就得是String) - Oracle
VARRAY有长度上限(如VARRAY(100) OF VARCHAR2(32)),Java 数组超长会导致 ORA-06531 - 传空集合时,不能传
null,应传空数组:new Object[0][]或new String[0] -
getArray().getArray()返回的是Object[],不是泛型集合;若元素是STRUCT,需逐个toJdbc()或toJdbcArray()转换
最常被忽略的一点:Oracle 自定义类型名在 JDBC 中必须全小写 schema + 大写 type 名(如 "sepadd.T_UPLOAD_FILE_TABLE"),而 PL/SQL 里可以混写。TypeMap 和 createARRAY() 的字符串参数必须完全一致,差一个字母或大小写就查不到类型映射。
立即学习“Java免费学习笔记(深入)”;


















