oracle Hibernate 自定义类型以避免'Caused by: java.sql.SQLException: Stream has been closed'

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10174951/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 00:43:59  来源:igfitidea点击:

Hibernate custom type to avoid 'Caused by: java.sql.SQLException: Stream has already been closed'

javaoraclehibernatecustom-type

提问by user1316131

How do I write a custom Long class to handle long values in Oracle, to avoid the following error?

如何编写自定义 Long 类来处理 Oracle 中的 long 值,以避免出现以下错误?

Caused by: java.sql.SQLException: Stream has already been closed.

引起:java.sql.SQLException:流已经被关闭。

Thanks

谢谢

回答by Anonymous

Oracle recommends not usingLongand Long Rawcolumns (since Oracle 8i). They are included in Oracle only for legacy reasons. If you really need to use them, the you should first handle these columns before attempting to touch any other columns in the ResultSet:

Oracle建议不要使用LongLong Raw列(从 Oracle 8i 开始)。它们仅出于遗留原因包含在 Oracle 中。如果您确实需要使用它们,您应该首先处理这些列,然后再尝试接触 中的任何其他列ResultSet

Docs:

文档

When a query selects one or more LONG or LONG RAW columns, the JDBC driver transfers these columns to the client in streaming mode. After a call to executeQuery or next, the data of the LONG column is waiting to be read.

Do not create tables with LONG columns. Use large object (LOB) columns, CLOB, NCLOB, and BLOB, instead. LONG columns are supported only for backward compatibility. Oracle recommends that you convert existing LONG columns to LOB columns. LOB columns are subject to far fewer restrictions than LONG columns.

当查询选择一个或多个 LONG 或 LONG RAW 列时,JDBC 驱动程序以流模式将这些列传输到客户端。在调用 executeQuery 或 next 之后,LONG 列的数据正在等待读取。

不要创建带有 LONG 列的表。请改用大对象 (LOB) 列、CLOB、NCLOB 和 BLOB。支持 LONG 列只是为了向后兼容。Oracle 建议您将现有的 LONG 列转换为 LOB 列。LOB 列受到的限制比 LONG 列少得多。

As for hibernate - see this question.

至于休眠 - 请参阅此问题

回答by Pablo

The following doesn't answer the original question 'how to write a custom Long class to handle long values in Oracle' but may be helpful to avoid the 'Stream has already been closed' error when querying Oracle long raw columns.

以下内容没有回答原始问题“如何编写自定义 Long 类来处理 Oracle 中的长值”,但可能有助于在查询 Oracle 长原始列时避免“流已关闭”错误。

We faced this error using a legacy database with no chances of changing the column type. We use Spring with hibernate3 session factory and transaction manager. The problem occurred when more than one task were accessing the DAO concurrently. We are using ojdbc14.jar driver and tried a newer one with no luck.

我们使用旧数据库遇到了这个错误,而没有机会更改列类型。我们将 Spring 与 hibernate3 会话工厂和事务管理器一起使用。当多个任务同时访问 DAO 时会出现问题。我们正在使用 ojdbc14.jar 驱动程序并尝试了一个更新的驱动程序,但没有成功。

Setting useFetchSizeWithLongColumn = true in the connection properties for the OJDBC driver solved the problem. See the OracleDriver API

在 OJDBC 驱动程序的连接属性中设置 useFetchSizeWithLongColumn = true 解决了这个问题。请参阅OracleDriver API

THIS IS A THIN ONLY PROPERTY. IT SHOULD NOT BE USED WITH ANY OTHER DRIVERS. If set to "true", the performance when retrieving data in a 'SELECT' will be improved but the default behavior for handling LONG columns will be changed to fetch multiple rows (prefetch size). It means that enough memory will be allocated to read this data. So if you want to use this property, make sure that the LONG columns you are retrieving are not too big or you may run out of memory. This property can also be set as a java property : java -Doracle.jdbc.useFetchSizeWithLongColumn=true myApplication

这是一个薄的财产。它不应与任何其他驱动程序一起使用。如果设置为“true”,则在“SELECT”中检索数据时的性能将得到改善,但处理 LONG 列的默认行为将更改为获取多行(预取大小)。这意味着将分配足够的内存来读取这些数据。因此,如果您想使用此属性,请确保您正在检索的 LONG 列不会太大,否则您可能会耗尽内存。此属性也可以设置为 java 属性: java -Doracle.jdbc.useFetchSizeWithLongColumn=true myApplication

回答by John Neville

I think you get this message when you try to get an Oracle LONG value from the result set multiple times.

我认为当您多次尝试从结果集中获取 Oracle LONG 值时,您会收到此消息。

I had code like:

我有这样的代码:

        rs.getString(i+1) ;
        if (rs.wasNull()) continue ;

        set(queryAttr[i], rs.getString(i+1)) ;

And I started getting the "Stream has already been closed." error. I stopped getting the error when I changed the code to:

我开始收到“流已经关闭”。错误。当我将代码更改为:

        String str = rs.getString(i+1) ;
        if (rs.wasNull()) continue ;

        set(queryAttr[i], str) ;

回答by steve thiboutot

This happens in a query of system tables:

这发生在系统表的查询中:

SELECT * FROM all_tab_columns
WHERE owner = 'D_OWNER' AND COLUMN_NAME LIKE 'XXX%';