java 21 连接 oracle 23ai 必须使用 ojdbc17-23.6.0.24.07.jar,因其完整支持 jdbc 4.3 和 jdk 21;ojdbc8.jar 仅支持 jdbc 4.2,会导致 vector 操作失败、ora-00904 报错或静默降级,且连接 url 必须显式添加 oracle.net.disableocm=true 参数。

Java 21 连接 Oracle 必须用 ojdbc17.jar,不是 ojdbc8
Oracle 23ai 官方从 ojdbc17-23.6.0.24.07 版本起才完整支持 JDBC 4.3 和 JDK 21。用 ojdbc8.jar(哪怕你强行放在 JDK 21 环境里)会导致:
• java.lang.UnsupportedOperationException: VECTOR type not supported —— 实际是驱动不识别类型,不是 Java 或数据库不支持
• 执行 VECTOR_DISTANCE 时抛 ORA-00904: invalid identifier —— 驱动未将函数转发为 Oracle 内置函数,而是当普通字段处理
• INMEMORY 列、JSON 表达式、新日期类型等特性静默降级或报错
正确做法:
• Maven 中声明:
<dependency><br><groupid>com.oracle.database.jdbc</groupid><br><artifactid>ojdbc17</artifactid><br><version>23.6.0.24.07</version><br></dependency>
• 手动下载时,务必核对文件名是否含
23.6.0.24.07 —— 23.5.x 版本不含向量支持,23.6.0.24.05 等小版本也可能缺失关键修复
连接 URL 必须加 oracle.net.disableOcm=true
Oracle 23ai 的 OCM(Oracle Configuration Manager)组件在 JDK 21 的虚拟线程(Project Loom)环境下存在资源泄漏,不显式禁用会导致:
• 连接池缓慢耗尽,新连接创建失败
• 已关闭连接长期停留在 CLOSE_WAIT 状态,netstat 可见大量堆积
• 无明确异常日志,排查困难
这个参数必须作为 URL 查询参数拼接,不能靠配置文件或 DataSource.setProperty() 设置:
• ✅ 正确:jdbc:oracle:thin:@//localhost:1521/FREEPDB1?oracle.net.disableOcm=true&useUnicode=true&characterEncoding=UTF-8
• ❌ 错误:ojdbc.properties 里写 oracle.net.disableOcm=true(不生效)
• ❌ 错误:Spring Boot 中用 hikari.connection-init-sql 绕过(OCM 在连接建立前就已触发)
• Easy Connect Plus 格式(如 @mydb.example.com:1521/free?)也需把该参数追加在末尾
向量字段插入必须 unwrap 为 OracleConnection
JDBC 规范本身没有定义 VECTOR 类型映射逻辑,所以标准的 PreparedStatement.setObject(1, floatArray, Types.ARRAY) 在 Oracle 23ai 上必然失败 —— 驱动不会自动把 Java float[] 转成数据库 VECTOR。
必须绕过 JDBC 标准层,走 Oracle 原生路径:
• 先调用 connection.unwrap(OracleConnection.class)
• 再用 OraclePreparedStatement 的 setARRAY() 或 setVector() 方法(取决于驱动版本封装)
• 示例片段:
OracleConnection oraConn = conn.unwrap(OracleConnection.class);<br>OraclePreparedStatement ps = (OraclePreparedStatement) oraConn.prepareStatement(<br> "INSERT INTO docs (id, embedding) VALUES (?, ?)");<br>ps.setInt(1, 123);<br>// 假设 embedding 是 VECTOR(384)<br>ps.setVector(2, new Vector(floatArray)); // 注意:不是 setObject
• 若用 Spring JDBC Template,需通过
getNativeJdbcExtractor().unwrapNativeConnection() 获取原生连接
老项目升级 JDK 21 时最容易忽略的点
很多团队只换 JDK、换驱动,却漏掉两件事:
• 没检查连接字符串是否带 oracle.net.disableOcm=true —— 表现是“偶尔连不上”“压测后连接数暴涨”,但日志干净得像没出事
• 没重写所有涉及向量、JSON、INMEMORY 的 DAO 层代码 —— 旧代码用 setObject(..., Types.ARRAY) 看似能跑,实则写入的是空值或乱码,查询时才发现数据不对
• ojdbc17.jar 是 JDK 17 编译的,但兼容 JDK 21;它不兼容 JDK 11 或更早版本,若项目混用多 JDK 环境,需确认 classpath 无冲突
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











