spring+hibernate 中clob的使用

        最近在做一个博客,里面的content字段本来是使用varchar2(4000),但是实际使用发现最多只能存入600多个字符,很奇怪,具体原因还不知道。在同事建议下决定使用clob来存储大文本;

        在网上查阅了一些资料,其中一种方法是: 

在hbm文件中加 

xml 代码
  1. <property name="content" type="text">  
  2.         <column name="CONTENT" length="100000" />  
  3.     property>  

 在.java中把content字段设为String类型,就可以把clob当作varchar来操作,但是存储时就出错

streams type cannot be used in batching

之后修改ssessionfactory

xml 代码
  1. <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
  2.         <property name="dataSource" ref="dataSource" />  
  3. <property name="configLocations">  
  4. <list>  
  5.                 <value>classpath:config/application.cfg.xmlvalue>  
  6.                 <value>classpath:config/basecommon.cfg.xmlvalue>  
  7.                 <value>classpath:config/parameter.cfg.xmlvalue>  
  8. list>  
  9. property>  
  10. <property name="hibernateProperties">  
  11. <props>  
  12. <prop key="hibernate.dialect">....prop>  
  13. <prop key="hibernate.show_sql">trueprop>  
  14. <prop key="hibernate.format_sql">trueprop>  
  15. <prop key="hibernate.jdbc.batch_size">0prop>  
  16. props>  
  17. property>  
  18. bean>  

把batch_size设为0,之后存储很小的文本时可以正常了,但是文本一大起来,就出错

Connection reset  SQL Error: 17002, SQLState: null

上网查,得知Oracle BLOB/CLOB 字段本身拥有一个游标(cursor),JDBC通过游标对Blob/Clob字段进行操作,在Blob/Clob字段创建之前,无法获取其游标句柄,会出现
Connection reset by peer: socket write error 异常。

正确的做法是:首先创建一个空 Blob/Clob 字段,再从这个空 Blob/Clob字段获取游标。

觉得和我的错误应该差不多,于是改写代码:

xml 代码
  1. <property name="contentClob" type="clob">  
  2.         <column name="CONTENT" length="100000" />  
  3.     property>  
java 代码
  1. blog.java中   
  2. ......   
  3. private Clob contentClob;   
  4. private String content   
  5.   
  6. ......   
  7. action中   
  8. Session ssesion = persistence.getHibernateSession();   
  9. Transaction ts = ssesion.beginTransaction();   
  10. .......   
  11. blog.setAuthor(author);   
  12. blog.setContent(Hibernate.createcontentClob(" "));   
  13. blog.setTitle(title);   
  14. ssesion.save(blog);   
  15. ssesion.flush();   
  16. ssesion.refresh(blog,LockMode.UPGRADE);   
  17. CLOB clob = (CLOB)blog.getcontentClob();   
  18. Writer wt=Clob.getCharacterOutputStream();   
  19. String content = blog.getContent();   
  20. wt.write(content);   
  21. wt.close();   
  22. .......   

这样的话,会抛出类型classCast的异常,在javaeye上看了robbin的一个帖子,中间lovehibernate说了一个解决方法:

使用hibernate.lob.SerializableClob来帮助类型转换;

把CLOB clob=(CLOB)blog.getcontentClob();换为

java 代码
  1. SerializableClob clob=(SerializableClob)informationContent.getContent();    
  2. java.sql.Clob wrapClob = clob.getWrappedClob();    
  3. CLOB tmpClob=(CLOB)wrapClob;    
  4. Writer wt=tmpClob.getCharacterOutputStream();   

问题基本解决,可以正常插入了。

update的代码基本上相同:

java 代码
  1. Session ssesion = persistence.getHibernateSession();   
  2.        Transaction ts = ssesion.beginTransaction();   
  3.        Blog blog = (Blog)ssesion.load(Blog.class,this.blog.getId(),LockMode.UPGRADE);       
  4.        ......   
  5.        blog.setContent(this.blog.getContent()); 
  6.        blog.setContentClob(Hibernate.createClob(" "));  
  7.        ......   
  8.        ssesion.update(blog);   
  9.        ssesion.flush();   
  10.   
  11.        ssesion.refresh(blog, LockMode.UPGRADE);   
  12.        SerializableClob clob = (SerializableClob) blog.getContentClob();   
  13.        java.sql.Clob wrapClob = clob.getWrappedClob();   
  14.        CLOB tmpClob = (CLOB) wrapClob;   
  15.        Writer wt = tmpClob.getCharacterOutputStream();   
  16.        String content = blog.getContent();   
  17.        wt.write(content);  

如果不使用第3行那句,会报:未锁定含有 LOB 值的行 的异常.

如果不使用第6行那句,结果给字段添加内容的时候可以update成功,但是删除字段内容的时候则不会有任何效果

后来数据库改用oralce10g,发现在jdbc的包中,getCharacterOutputStream()方法都被deprecated了,于是修改为:

 

java 代码
  1. Writer wt = tmpClob.setCharacterStream(0);   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值