最近在做一个项目,原先是用Mysql数据库开发的,现在因客户要求,迁移到oracle。
开发的环境是,wsi(webwork+spring+ibaits).
数据库的字符集是UTF-8.
迁移过程中,碰到了这样一个问题,向一个表中执行update和insert操作时,类型为CLOB列的就出现异常
异常为:
仅可以为插入 LONG 列的 LONG 值赋值 CLOB
............
当时上网查了,有很多人也碰到了相同的问题,总体而言有两种解决方式,
第一种是驱动版本过低。
第二种是修改hibernate的配置文件,当时,前提是你开发的持久层必须是hibernate。
我从oracle官方网站下了一个最新的JDBC驱动(通过附件上传了),运行还是报哪个错误。没有效果。
而第二种方法,对于我而言,是肯定行不通的。
网上有部分人说,值长度在2000-4000之间会出现异常,
可是,我的不同,
我的是值的长度在1000-2000之间会出现异常,稍短或长都没问题。
在这里说明一下,肯定不会是因为长度限制的问题,因为CLOB在ORACLE里面,所输入的可达4G。
对于LONG,这个类型我没用过,在ORACLE里面也不建议用。是一个已经被废弃了的类型。
最后我的解决方法是,在视图层,对所输入的进行判断,把少了的用空格不上,在jsp中,四个空格等于一个字符的长度。
让其长度超过2000即可,但是,这种方法对于紧急情况可能还不错,而效率上就不说了。
还有,就是说,如果你的长度不会超过2000,就建议用varchar2,但是需要注意的是数据库字符集应该是UTF-8的,对于UTF-8或欧洲的某些字符集,oracle在存储时,对于一个字符需要2个或3个字节的存储空间,虽然表定义中varchar2(4000),但是其实该字段的data_length为其2倍或3倍长。
在这里,也顺便把在网上看到的,关于hibernate修改配置的方法,粘贴出来.
Hibernate實體對象中的数据成员类型为String,映射的数据库字段类型为org.springframework.orm.hibernate.support.ClobStringType 。實例如下:
@SuppressWarnings( " serial " ) @Entity @Table(name = " GUIDE " ) // @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class Guide { @Type(type = " org.springframework.orm.hibernate3.support.ClobStringType " ) private String content; // 内容 // get & set }
如果使用Spring的这个Clob类型就需要在applicationContext.xml中的sessionFactory bean里注入oracleLobHandler bean。下面給出Oracle數據庫的LobHandler配置
< bean id ="oracleLobHandler" class ="org.springframework.jdbc.support.lob.OracleLobHandler" lazy-init ="true" > < property name ="nativeJdbcExtractor" ref ="nativeJdbcExtractor" /> </ bean > < bean id ="nativeJdbcExtractor" class ="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor" lazy-init ="true" /> <!-- Hibernate SessionFactory --> < bean id ="sessionFactory" class ="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" > < property name ="dataSource" ref ="dataSource" /> < property name ="configLocation" value ="classpath:hibernate/hibernate.cfg.xml" /> < property name ="hibernateProperties" > < value > </ value > </ property > < property name ="lobHandler" ref ="oracleLobHandler" /> </ bean >
< bean id ="defaultLobHandler" class ="org.springframework.jdbc.support.lob.DefaultLobHandler" lazy-init ="true" /> < bean id ="testDao" class ="com.test.dao.jdbc.TestJdbcDao" > < property name ="lobHandler" ref =" defaultLobHandler" /> < property name ="jdbcTemplate" ref ="jdbcTemplate" /> </ bean >
DefaultLobHandler 只是简单地代理标准 JDBC 的 PreparedStatement 和 ResultSet 对象,由于并不需要访问数据库驱动本地的 JDBC 对象,所以它不需要 NativeJdbcExtractor 的帮助。
希望总有一张方法能帮你解决掉麻烦的ORA-01461。
如果,哪位有更好的解决方法,就麻烦分享一下了。