hibernate 保存clob,blob出现的问题

在oracle中,用hibernate操作clob对象花了三天时间。终于把他弄对了。

 

前提:oracle中用一个clob字段。hbm.xml中对应的是java.sql.Clob/

 

 

 <property
            name="answer"
            type="java.sql.Clob"
            update="true"
            insert="true"
            column="answer"
        />

 

 

pojo中:

    

               ....... 其他属性
               private java.sql.Clob;

                 public Clob getAnswer() {
		return this.answer;
	}

	public void setAnswer(Clob answer) {
		this.answer = answer;
	}
                .........其他方法

 

存储的时候用session.save(obj)的方法;

这样做 clob属性中数据少的时候没报错。但数据量大的时候就会抛莫名其妙的异常。

问题出在Oracce中Blob/Clob字段独特的访问方式,Oracle Blob/Clob字段本身拥有一个游标(cursor) , JDBC必须通过游标对Blob/ Clob字段进行操作,在Blob/Clob字段被创建之前,我们无法获取其游标句柄,这也就意味着,我们必须首先创建一个空Blob/Clob字段,再从这个空Blob/Clob字段获取游标,写入我们所期望保存的数据。

至于如何操作可参考本博客其他文章(转载的)。

 

这里主要讲述两个异常

 

(1) java.lang.ClassCastException : org.hibernate.lob.clobImpl 转型异常

   原因:用hibernateTemplate.save(),或者session.save()保存完对象后发现其对象的类型是clobImpl的。

   此时强制转化就会报错。

   解决方法:要用session.refresh()方法。也就是说refresh()方法必须在取clob对象之前。

 (2) ORA-01002: 读取违反顺序

  原因:在refresh方法的时候导致的

  解决方法:用session开始一个事务。然后就最后末事务在提交。(至于为什么,我也不清楚)

 

上述主要涉及的是hibernate存储clob,若直接用jdbc同样注意两个错误。

(1)ORA-01002: 读取违反顺序

 同上原理。设置connection 自动提交为false,

                conn.setAutoCommit(false);

(2)ORA-22920: 未锁定含有 LOB 值的行

  在select 时候 要加上 “for update ”

例子:

Connection conn = getConnection();
          	  conn.setAutoCommit(false);
         	  PreparedStatement p=conn.prepareStatement("select * from train_test where id='"+po.getId()+"' for update");
         	  ResultSet rs = p.executeQuery(); 
           	  rs.next();
         	  CLOB testDesc= (CLOB) rs.getClob("test_desc");
            	  CLOB answer= (CLOB) rs.getClob("answer");
         	  
        	  testDesc.putString(1, getValue(ret,"试题题目"));
          	  answer.putString(1, getValue(ret,"试题答案"));
           	  p=conn.prepareStatement("update train_test set  test_desc=? ,answer=?");
          	  p.setClob(1, testDesc);
       	  p.setClob(2, answer);
        	  p.executeUpdate();
          	  conn.commit();   
            	 

   

写完,收工。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值