4

我正在尝试向 Oracle Clob 字段写入超过 4000 个字符的值。这似乎是一个常见问题,但似乎没有一种解决方案有效。所以我从这里祈求帮助。

Down and dirty info:
Using Oracle 9.2.0.8.0
Hibernate3 implementation pojo's with annotations
Tomcat 6.0.16
Oracle 10.2.x drivers
C3P0 connction pool provider

在我的 persistence.xml 我有:

<persistence-unit name="DWEB" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
        <property name="hibernate.archive.autodetection" value="class"/> 
        <property name="hibernate.connection.password" value="###" />
        <property name="hibernate.connection.username" value="###" />
        <property name="hibernate.default_schema" value="schema" />
        <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
        <property name="hibernate.c3p0.min_size" value="5" />
        <property name="hibernate.c3p0.max_size" value="20" />
        <property name="hibernate.c3p0.timeout" value="300" />
        <property name="hibernate.c3p0.max_statements" value="50" />
        <property name="hibernate.c3p0.idle_test_period" value="3000" />
        <property name="show_sql" value="true" />
        <property name="format_sql" value="true" />
        <property name="use_sql_comments" value="true" />
        <property name="SetBigStringTryClob" value="true"/>
        <property name="hibernate.jdbc.batch_size" value="0"/>
        <property name="hibernate.connection.url" value="jdbc:oracle:thin:@server.ss.com:1521:DDD"/>
        <property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver"/>
    </properties>
</persistence-unit>

getter 和 setter 看起来像:

@Lob 
@Column(name="COMMENT_DOC")
public String getDocument(){
    return get("Document");
}
public void setDocument(String s){
    put("Document",s);
}

我得到的例外是:

SEVERE: Servlet.service() for servlet SW threw exception
java.sql.SQLException: Io exception: Software caused connection abort: socket write error
    at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
    at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179)
    at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:334)
    at oracle.jdbc.ttc7.TTC7Protocol.handleIOException(TTC7Protocol.java:3678)
    at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1999)
    at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1144)
    at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2152)
    at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2035)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2876)
    at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:609)
    at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:46)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2275)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2688)
    at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
    at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:304)
    at org.sw.website.actions.content.AddComment.performAction(AddComment.java:60)
...

如果我需要提供更多信息,请询问。一切正常,直到超过可怕的限制。

4

4 回答 4

4

感谢非追随者的所有帮助。我有这个工作,我想我会把所有的东西放在这里以供将来参考。不管所有关于升级驱动程序的说法和一切都会奏效,但这些都对我不起作用。最后,我必须实现一个“org.hibernate.usertype.UserType”,我将其命名为与 Web StringClobType 上的所有示例相同。除了一些导入之外,我使用了Using Clobs/Blobs with Oracle and Hibernate中的示例。就我而言,忽略“当心”的说法。

我必须进行一项更改才能使合并工作。提供的代码示例中未实现某些方法。Eclipse 通过删除它们为我修复了它。很酷,但是需要实际实现替换方法,否则所有合并都会用空值覆盖数据。这是我的实现:

public Object replace(Object newValue, Object existingValue, Object arg2)throws HibernateException {
    return newValue;
}

我不会在这里复制类的实现去上面的链接看看。我使用了第三个灰色框中的代码。然后在我想在 pojo 类的顶部使用它,我在导入后添加了以下内容

...  
import org.hibernate.annotations.Type;  
import org.hibernate.annotations.TypeDefs;  
import org.hibernate.annotations.TypeDef;  

@TypeDefs({  
    @TypeDef(  
        name="clob",  
        typeClass = foo.StringClobType.class  
    )  
})  
@Entity  
@Table(name="EA_COMMENTS")  
public class Comment extends SWDataObject implements JSONString, Serializable {  
...  
}   

然后为了使用新的 UserType,我将注释添加到我的 getter 中:

@Type(type="clob")
@Column(name="COMMENT_DOC")
public String getDocument(){
    return get("Document");
}

我不需要 @Lob 注释。
在我的 persistence.xml 中,persistence-unit 声明的结尾看起来像:

<persistence-unit name="###" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
        <property name="hibernate.archive.autodetection" value="class"/> 
        <property name="hibernate.connection.password" value="###" />
        <property name="hibernate.connection.username" value="###" />
        <property name="hibernate.connection.url" value="jdbc:oracle:thin:@server.something.com:1521:###"/>
        <property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver"/>
        <property name="hibernate.default_schema" value="###" />
        <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9iDialect" />
        <property name="hibernate.c3p0.min_size" value="5" />
        <property name="hibernate.c3p0.max_size" value="100" />
        <property name="hibernate.c3p0.timeout" value="300" />
        <property name="hibernate.c3p0.max_statements" value="50" />
        <property name="hibernate.c3p0.idle_test period" value="3000" />
        <property name="hibernate.c3p0.idle_connection_test_period" value="300" />
        <property name="show_sql" value="false" />
        <property name="format_sql" value="false" />
        <property name="use_sql_comments" value="false" />
        <property name="hibernate.jdbc.batch_size" value="0"/>
    </properties>
</persistence-unit>

SetBigStringTryClob 从来没有为我工作过,也不需要这个最终实现。

我吸取的教训是,最终加入而不是战斗可能更好。它会节省我三天的时间。

于 2009-12-07T20:52:44.573 回答
3

我认为您的问题可能是您使用的是Oracle 9i但 Hibernate 方言是10g。确保您的驱动程序、数据库版本和方言都同步,因为还有 9i 方言org.hibernate.dialect.Oracle9iDialect

于 2009-12-04T20:15:09.167 回答
3

它应该是:

<property name="hibernate.connection.SetBigStringTryClob">true</property>
<property name="hibernate.jdbc.batch_size">0</property>

并不是:

<property name="SetBigStringTryClob">true</property>

并为您的数据库使用正确的方言 ( org.hibernate.dialect.Oracle9iDialect)。

还要确保您使用的是最新的Oracle 10g 第 2 版瘦驱动程序(10.2.0.4) 或更高版本。

于 2010-01-25T07:13:16.453 回答
0

我们过去也遇到过类似的问题,使用 LONG 列而不是 CLOB。问题是 JDBC 驱动程序,我们现在使用并且运行良好的是替代文字

于 2009-12-04T16:25:04.290 回答