论坛首页 Java企业应用论坛

oracle clob问题

浏览 19527 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-05-14  
最初的问题表象估计和大部分的情形差不多,报告 streams type cannot be used in batching 错误。

我用了 ImmutableType 方式,定义了StringClobType extends ImmutableType 如下:
public class StringClobType extends ImmutableType {
        public Object get(ResultSet rs, String name);
                throws HibernateException, SQLException {
                Clob clob = rs.getClob(name);;
                if (clob==null); {
                    return "";
                }
                return clob.getSubString(1, (int); clob.length(););;
        }
        public void set(PreparedStatement st, Object value, int index);
                throws HibernateException,SQLException {
                StringReader r = new StringReader((String); value);;
                st.setCharacterStream(index, r, ((String); value);.length(););;
        }
        public int sqlType(); {
                return Types.CLOB;
        }
        public String getName(); {
                return "string";
        }
        public boolean hasNiceEquals(); {
                return false;
        }
        public boolean equals(Object x, Object y); {
                return ObjectUtils.equals(x, y);;
        }
        public String toXML(Object value); {
                return (String); value;
        }
        public Class getReturnedClass(); {
                return Clob.class;
        }
        public Object fromStringValue(String xml); {
                throw new UnsupportedOperationException();;
        }

        public String toString(Object value); {
                return value.toString();;
        }
}


用这种方式处理小记录(小于4000字节)可以,但是当大字段的时候,总是报告streams type cannot be used in batching 。

网上查阅的大量资料,中文的,国外的,什么hibernate 56,73文档。包括在这个论坛进行了大范围的搜索。
最后尝试了两种方式,在配置文件中,指明 hibernate.jdbc.batch_size为0 ;或者 hibernate.jdbc.use_streams_for_binary为true。设置对于hibernate.jdbc.use_streams_for_binary 设置的时候,在jvm环境中设置了。

结果确实不出现streams type cannot be used in batching 错误,却报告flush错误。

可以说,我的存储很简单。采用了 extends ImmutableType 之后。而且,对所有的clob字段,在bo对象中采用String类型映射数据库的blob字段 一个
session.save(object); 就完成(当然省略了很多代码)。

网上也发现,采用下面的方式可行
Session s = sf.openSession();; 
tx = s.beginTransaction();; 
foo = new Foo();; 
foo.setClob( Hibernate.createClob(" "); );; 
s.save(foo);; 
s.flush();; 
s.refresh(foo, LockMode.UPGRADE);; //grabs an Oracle CLOB 
oracle.sql.CLOB clob = (oracle.sql.CLOB); foo.getClob();; 
java.io.Writer pw = clob.getCharacterOutputStream();; 
pw.write(content);; 
pw.close();; 
tx.commit();; 
s.close();;


但这种方式,bo必须指明clob属性,而且一般情况下每个操作似乎都必须是单独的代码,有些费时。

不知道,这个问题,谁良好的解决了,能否详细的说明。

备注环境:
db: oralce9i
dbdriver: oracle.jdbc.sql.OracleDriver
Hibernate: Hibernate2.1.2
App:JBoss
测试阶段,没有采用connection pool


Thanks!
   发表时间:2004-05-14  
插入
      bo.setContentClob(Hibernate.createClob(" "););;
      session.save(bo);;
      session.flush();;
      session.refresh(bo, LockMode.UPGRADE);; //grabs an Oracle CLOB
      oracle.sql.CLOB clob = (oracle.sql.CLOB); bo.getContentClob();;
      java.io.Writer pw = clob.getCharacterOutputStream();;
      pw.write(content);;
      pw.flush();;
      pw.close();;
      session.flush();;


更新
      bo.setContentClob(Hibernate.createClob(" "););;
      session.update(bo);;
      session.flush();;
      session.refresh(bo, LockMode.UPGRADE);; //grabs an Oracle CLOB
      oracle.sql.CLOB clob = (oracle.sql.CLOB); bo.getContentClob();;
      //注:如果是用weblogic connection pool,则用weblogic的OracleThinClob
      java.io.Writer pw = clob.getCharacterOutputStream();;
      pw.write(content);;
      pw.flush();;
      pw.close();;
      session.flush();;


这种方式暂时搞定了问题,不过对于不太灵活,累赘啊。几乎不同的DAO就如需要重新写。

考虑如何更好的解决···思考中···
0 请登录后投票
   发表时间:2004-05-14  
我手头没有Oracle,你试试看
0 请登录后投票
   发表时间:2004-05-14  
我有个权宜的解决方法,就是用OCI驱动。用text类型。这是udoo发现的。可以正常的把大string转换为clob存储
0 请登录后投票
   发表时间:2004-05-15  
引用

这是udoo发现的。可以正常的把大string转换为clob存储

呵呵,这也是我这种解决方案的关键,我记得在Oracle下也是可以的
0 请登录后投票
   发表时间:2004-05-16  
potian 写道

呵呵,这也是我这种解决方案的关键,我记得在Oracle下也是可以的


不知道为什么Oracle不把这个功能做到thin驱动里面
0 请登录后投票
   发表时间:2004-05-16  
冰云 写道
我有个权宜的解决方法,就是用OCI驱动。用text类型。这是udoo发现的。可以正常的把大string转换为clob存储


谢谢各位的热情解答.

看来这个问题可以从oracle驱动方面着手,只是oci驱动,不太适合商业大范围应用,不知道有没有人用过“第三方的驱动”?——正如商业应用中,很少用ms的mssqlserver驱动一样。

刚才也顺便想了一下,看来还有种方式,就是扩展或修改hibernate代码,从内部屏蔽掉这个问题。(看来要花点心思读代码了)
(很奇怪的事,为什么hibernate本身不能够争取的支持呢?难道都是鼓励大家花钱用第三方的驱动?)
0 请登录后投票
   发表时间:2004-05-16  
银狐999 写道


谢谢各位的热情解答.

看来这个问题可以从oracle驱动方面着手,只是oci驱动,不太适合商业大范围应用,不知道有没有人用过“第三方的驱动”?——正如商业应用中,很少用ms的mssqlserver驱动一样。

刚才也顺便想了一下,看来还有种方式,就是扩展或修改hibernate代码,从内部屏蔽掉这个问题。(看来要花点心思读代码了)
(很奇怪的事,为什么hibernate本身不能够争取的支持呢?难道都是鼓励大家花钱用第三方的驱动?)


我在Google搜索过,有好几个第三方的驱动,不过都是要钱的 
oci怎么不是和商业大范围应用呢? 想一下,安装大的商业应用的服务器,
肯定是可以进行操作的,同时安装一个Oracle client也是完全没问题的嘛~
再说OCI基于JNI,速度比thin要快。
0 请登录后投票
   发表时间:2004-05-16  
OCI8未必比Thin快。在通常意义上来理解,Thin是用纯Java写的,是通过Socket连接Oracle TNS Listener来操作,而OCI8则是Java调用本地Oracle Client C Library,然后由C去连接Oracle TNS Listener。因此大家一定都会直观的以为OCI8快。

但是我曾经做过很多次测试,在Windows/Linux平台上运行Oracle8i,JDBC Driver为classes12.zip,事实证明当不使用数据库连接池的时候,OCI8速度要比Thin快,但是在使用数据库连接池的情况下,Thin速度要超过OCI8不少。
0 请登录后投票
   发表时间:2004-05-16  
robbin 写道
OCI8未必比Thin快。在通常意义上来理解,Thin是用纯Java写的,是通过Socket连接Oracle TNS Listener来操作,而OCI8则是Java调用本地Oracle Client C Library,然后由C去连接Oracle TNS Listener。因此大家一定都会直观的以为OCI8快。

但是我曾经做过很多次测试,在Windows/Linux平台上运行Oracle8i,JDBC Driver为classes12.zip,事实证明当不使用数据库连接池的时候,OCI8速度要比Thin快,但是在使用数据库连接池的情况下,Thin速度要超过OCI8不少。


  原来是这样,没测过~~
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics