Java 休眠 > CLOB > Oracle :(
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1843484/
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
Hibernate > CLOB > Oracle :(
提问by Mark
I am trying to write to an Oracle clob field a value over 4000 characters. This seams to be a common issue but non of the solutions seem to work. So I pray for help from here.
我正在尝试向 Oracle clob 字段写入超过 4000 个字符的值。这似乎是一个常见问题,但似乎没有任何解决方案有效。所以我在这里祈求帮助。
Down and dirty info:
Using Oracle 9.2.0.8.0
Hibernate3 implementing pojo's with annotations
Tomcat 6.0.16
Oracle 10.2.x drivers
C3P0 connction pool provider
故障和脏信息:使用 Oracle 9.2.0.8.0
Hibernate3 实现带有注释的 pojo
Tomcat 6.0.16
Oracle 10.2.x 驱动程序
C3P0 连接池提供程序
In my persistence.xml I have:
在我的 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>
The getter and setter looks like:
getter 和 setter 看起来像:
@Lob
@Column(name="COMMENT_DOC")
public String getDocument(){
return get("Document");
}
public void setDocument(String s){
put("Document",s);
}
The exception I am getting is:
我得到的例外是:
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)
...
If I need to give more info pleas ask. Everything works until the dreaded limit is exceeded.
如果我需要提供更多信息,请询问。一切正常,直到超出可怕的限制。
采纳答案by Mark
Thanks to non sequitor for all the help. I have this working and figure I will put all the pieces here for future reference. Regardless of all the claims about upgrading the drivers and everything would work, non of that worked for me. In the end I had to implement a 'org.hibernate.usertype.UserType' I named it the same as all the examples on the web StringClobType. Save for some imports I used the example from Using Clobs/Blobs with Oracle and Hibernate. As far as I am concerned ignore the "beware" claim.
感谢非 sequitor 的所有帮助。我有这个工作和数字我会把所有的部分放在这里以供将来参考。不管关于升级驱动程序的所有声明和一切都会起作用,但对我来说没有任何作用。最后,我必须实现一个“org.hibernate.usertype.UserType”,我将它命名为与 Web 上所有示例 StringClobType 相同的名称。除了一些导入,我使用了Using Clobs/Blobs with Oracle and Hibernate 中的示例。就我而言,忽略“当心”的说法。
There was one change I had to make to get merges to work. Some of the methods were not implemented in the provided code sample. Eclipse fixed it for me by stubbing them out. Cool, but the replace method needs to be actually implemented or all merges will overwrite the data with a null. Here is my implementation:
我必须进行一项更改才能使合并工作。某些方法未在提供的代码示例中实现。Eclipse 通过剔除它们为我修复了它。很酷,但是替换方法需要实际实现,否则所有合并都会用空值覆盖数据。这是我的实现:
public Object replace(Object newValue, Object existingValue, Object arg2)throws HibernateException {
return newValue;
}
I will not duplicate the class implementation here go to the above link to see it. I used the code in the third gray box. Then at the top of the pojo class I wanted to use it in I added the following after the imports
我不会在这里复制类的实现去上面的链接看。我使用了第三个灰色框中的代码。然后在 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 {
...
}
Then to use the new UserType I added the annotation to my getter:
然后为了使用新的 UserType,我在 getter 中添加了注释:
@Type(type="clob")
@Column(name="COMMENT_DOC")
public String getDocument(){
return get("Document");
}
I did not need the @Lob annotation.
In my persistence.xml the persistence-unit declaration ended looking like:
我不需要@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>
The SetBigStringTryClob never worked for me and was not needed for this final implementation.
SetBigStringTryClob 从来没有为我工作过,也不需要这个最终实现。
My lesson learned is in the end it is probably better to join then to fight. It would of saved me three days.
我的教训是,最终加入然后战斗可能更好。它可以为我节省三天时间。
回答by Lluis Martinez
回答by non sequitor
I think your problem might be that you are using Oracle 9ibut Hibernate dialect is 10g. Make sure your driver,db version and dialect are all in sync because there is a 9i dialect as well org.hibernate.dialect.Oracle9iDialect
我认为您的问题可能是您使用的是Oracle 9i但 Hibernate 方言是10g。确保您的驱动程序、数据库版本和方言都同步,因为还有 9i 方言org.hibernate.dialect.Oracle9iDialect
回答by Pascal Thivent
It should be:
它应该是:
<property name="hibernate.connection.SetBigStringTryClob">true</property>
<property name="hibernate.jdbc.batch_size">0</property>
And not:
并不是:
<property name="SetBigStringTryClob">true</property>
And use the right dialect for your database (org.hibernate.dialect.Oracle9iDialect
).
并为您的数据库使用正确的方言 ( org.hibernate.dialect.Oracle9iDialect
)。
Also make sure that you are using the latest Oracle 10g Release 2 thin driver(10.2.0.4) or later.
还要确保您使用的是最新的Oracle 10g 第 2 版瘦驱动程序(10.2.0.4) 或更高版本。