我试图将一个超过4000个字符的值写入Oracle Clob字段。这似乎是一个普遍的问题,但是似乎没有解决方案可以奏效。所以我从这里祈祷寻求帮助。
故障和肮脏的信息:使用Oracle 9.2.0.8.0 Hibernate3实现带有注释 Tomcat的pojo Tomcat 6.0.16 Oracle 10.2.x驱动程序 C3P0连接池提供程序
在我的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) ...
如果我需要提供更多信息,请询问。一切工作直到超过可怕的限制。
感谢非续集者的所有帮助。我已经完成了这项工作,并确定了所有内容,以备将来参考。不管所有关于升级驱动程序的主张,一切都会奏效,但对我而言,一切都不奏效。最后,我必须实现一个“ org.hibernate.usertype.UserType”,我将其命名为与Web StringClobType上的所有示例相同。除了一些导入,我使用了“ 在Oracle和Hibernate中使用Clobs / Blobs”中的示例。就我而言,请忽略“提防”声明。
为了使合并生效,我必须进行一项更改。所提供的代码示例中未实现某些方法。Eclipse通过暂存它们为我修复了它。很酷,但是replace方法实际上需要实现,否则所有合并将使用null覆盖数据。这是我的实现:
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 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从来没有为我工作,并且此最终实现不需要它。
我吸取的教训是,最终加入战斗可能会更好。它将为我节省三天。