必须使用ojdbc17.jar(23.6+版本),因其完整支持jdbc 4.3、jdk 21及oracle 23ai向量特性;ojdbc8.jar仅支持jdbc 4.2,会导致vector操作失败或静默降级。

Java 21 连接 Oracle 23ai 必须用 ojdbc17.jar,不能用 ojdbc8
Oracle 23ai 官方 JDBC 驱动从 23.6 版本起才完整支持 JDBC 4.3 和 JDK 21;ojdbc8.jar 最高只支持 JDBC 4.2,即使在 JDK 21 环境下运行,也会在向量操作、INMEMORY 列访问或 VECTOR_DISTANCE 调用时抛出 SQLException 或静默降级。必须使用 ojdbc17.jar(对应 JDK 17+ 编译,兼容 JDK 21)。
常见错误现象:
-
java.lang.UnsupportedOperationException: VECTOR type not supported—— 实际是驱动版本太低,不是类型本身不支持 - 连接成功但执行
VECTOR_DISTANCE报ORA-00904: invalid identifier—— 驱动未识别新函数,转发为普通字段引用
获取方式:
- Maven 坐标:
<groupid>com.oracle.database.jdbc</groupid><artifactid>ojdbc17</artifactid><version>23.6.0.24.07</version> - 手动下载:去 Oracle Maven 仓库或 OTN 下载页找
ojdbc17-23.6.0.24.07.jar,注意不要选错小版本(如 23.5.x 不含完整向量支持)
连接字符串必须加 oracle.net.disableOcm=true
Oracle 23ai 的 OCM(Oracle Configuration Manager)组件在 JDK 21 下与虚拟线程(Project Loom)存在资源泄漏冲突,不显式禁用会导致连接池缓慢耗尽、连接卡死在 CLOSE_WAIT 状态,且无明确报错。
正确写法(Thin 模式):
jdbc:oracle:thin:@//localhost:1521/FREEPDB1?oracle.net.disableOcm=true&useUnicode=true&characterEncoding=UTF-8
关键点:
-
oracle.net.disableOcm=true必须作为 URL 参数,不能放在ojdbc.properties或DataSourcesetProperty 中 —— 后者不生效 - 若用 Easy Connect Plus 格式(如
jdbc:oracle:thin:@mydb.example.com:1521/free?...),该参数仍需拼接在末尾 - Spring Boot 用户:在
application.yml的spring.datasource.url里直接追加,不要试图用hikari.connection-init-sql绕过
JDBC 绑定向量字段必须 unwrap 为 OracleConnection
标准 PreparedStatement.setObject(1, floatArray, Types.ARRAY) 在 Oracle 23ai 上必然失败,因为 JDBC 规范不定义 VECTOR 类型映射逻辑,驱动不会自动将 Java float[] 转为数据库 VECTOR。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
正确做法是绕过 JDBC 标准层,走 Oracle 原生路径:
- 先调用
connection.unwrap(OracleConnection.class) - 用
ArrayDescriptor.createDescriptor("VECTOR", oracleConn)创建描述符(注意大小写:必须是大写"VECTOR") - 用
new ARRAY(descriptor, oracleConn, floatArray)构造数组对象 - 再调用
ps.setARRAY(1, array),而非setObject
示例片段:
OracleConnection oc = conn.unwrap(OracleConnection.class);
ArrayDescriptor desc = ArrayDescriptor.createDescriptor("VECTOR", oc);
ARRAY vectorArray = new ARRAY(desc, oc, new float[]{0.1f, 0.2f, ..., 0.384f});
ps.setARRAY(1, vectorArray);
容易踩的坑:
- 传入的
float[]长度必须与表定义完全一致(如VECTOR(384, FLOAT32)就必须是 384 元素,少一位触发ORA-40697) - 如果用 Spring JdbcTemplate,需自定义
SqlTypeValue实现,否则update()会退化为 BLOB 写入
INMEMORY + 向量索引启用前必须确认 PDB 级别配置
Oracle 23ai 的向量搜索性能依赖 INMEMORY 列存储和专用索引,但这两者默认关闭,且开关粒度在 PDB 层 —— 即使 CDB 级开了,PDB 里仍需单独启用。
验证与启用命令(以 FREEPDB1 为例):
ALTER SESSION SET CONTAINER = FREEPDB1; SELECT parameter, value FROM v$option WHERE parameter = 'In-Memory Area'; -- 若为 FALSE,则执行: ALTER SYSTEM SET inmemory_size=2G SCOPE=SPFILE; SHUTDOWN IMMEDIATE; STARTUP;
接着建向量索引前,必须确保:
- 目标表已用
INMEMORY属性创建或修改:ALTER TABLE docs INMEMORY; - 向量列已定义为
VECTOR(384, FLOAT32),不能是RAW或BLOB - 执行
CREATE VECTOR INDEX idx_docs_vec ON docs(embedding) ONLINE;时,用户要有INHERIT PRIVILEGES权限(否则报ORA-01031)
最易被忽略的是:INMEMORY 开启后需重启 PDB 才生效,光 ALTER SYSTEM 不够;而向量索引创建失败时,错误信息常指向权限,实际根源可能是 INMEMORY 未就绪。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










