【发布时间】:2012-04-27 19:57:38
【问题描述】:
如何编写自定义 Long 类来处理 Oracle 中的 long 值,以避免出现以下错误?
原因:java.sql.SQLException:流已经关闭。
谢谢
【问题讨论】:
标签: java oracle hibernate custom-type
如何编写自定义 Long 类来处理 Oracle 中的 long 值,以避免出现以下错误?
原因:java.sql.SQLException:流已经关闭。
谢谢
【问题讨论】:
标签: java oracle hibernate custom-type
Oracle recommends not using Long 和 Long Raw 列(自 Oracle 8i 起)。它们仅出于遗留原因包含在 Oracle 中。如果您确实需要使用它们,您应该先处理这些列,然后再尝试触摸ResultSet 中的任何其他列:
Docs:
当查询选择一个或多个 LONG 或 LONG RAW 列时,JDBC 驱动程序以流模式将这些列传输到客户端。在调用 executeQuery 或 next 之后,LONG 列的数据正在等待读取。
不要创建包含 LONG 列的表。请改用大对象 (LOB) 列 CLOB、NCLOB 和 BLOB。支持 LONG 列仅是为了向后兼容。 Oracle 建议您将现有的 LONG 列转换为 LOB 列。 LOB 列受到的限制远少于 LONG 列。
至于休眠 - 请参阅question。
【讨论】:
ResultSet 获取列。可以先获取LONG RAW 列吗? (Oracle假设列是按从左到右的顺序访问的,当访问流列之后的列时关闭流)
以下内容没有回答原始问题“如何编写自定义 Long 类来处理 Oracle 中的长值”,但可能有助于避免在查询 Oracle 长原始列时出现“流已关闭”错误。
我们在使用旧数据库时遇到了这个错误,没有机会更改列类型。我们将 Spring 与 hibernate3 会话工厂和事务管理器一起使用。当多个任务同时访问 DAO 时会出现此问题。 我们正在使用 ojdbc14.jar 驱动程序并尝试了更新的驱动程序,但没有成功。
在 OJDBC 驱动程序的连接属性中设置 useFetchSizeWithLongColumn = true 解决了这个问题。见OracleDriver API
这只是一个薄属性。它不应该与任何其他人一起使用 司机。如果设置为“true”,则在检索数据时的性能 'SELECT' 将得到改进,但处理 LONG 的默认行为 列将更改为获取多行(预取大小)。它 意味着将分配足够的内存来读取这些数据。因此,如果 要使用此属性,请确保您的 LONG 列 检索不是太大,否则您可能会耗尽内存。这个性质 也可以设置为 java 属性:java -Doracle.jdbc.useFetchSizeWithLongColumn=true myApplication
【讨论】:
这发生在系统表的查询中:
SELECT * FROM all_tab_columns
WHERE owner = 'D_OWNER' AND COLUMN_NAME LIKE 'XXX%';
【讨论】:
我认为当您尝试从结果集中多次获取 Oracle LONG 值时会收到此消息。
我的代码如下:
rs.getString(i+1) ;
if (rs.wasNull()) continue ;
set(queryAttr[i], rs.getString(i+1)) ;
我开始收到“流已经关闭”。错误。当我将代码更改为:
String str = rs.getString(i+1) ;
if (rs.wasNull()) continue ;
set(queryAttr[i], str) ;
【讨论】: