今天遭遇由于ojdbc14.jar版本不正确导致ORA-01461和ORA-01483报错的问题。简单记录一下这个问题的处理过程。
1.应用程序报错现象
以下是从应用程序日志中截取的两段报错信息。
2011-05-05 04:24:28,148 INFO [org.iata.asdcore.acdm.esb.service.AcdmEsbServiceImpl] The number is ***********************986
2011-05-05 04:24:28,451 ERROR [org.hibernate.util.JDBCExceptionReporter] ORA-01461: can bind a LONG value only for insert into a LONG column
2011-05-05 04:24:28,451 ERROR [org.hibernate.util.JDBCExceptionReporter] ORA-01461: can bind a LONG value only for insert into a LONG column
2011-05-05 04:24:28,451 ERROR [org.hibernate.event.def.AbstractFlushingEventListener] Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
2011-05-03 19:10:14,414 ERROR [org.hibernate.util.JDBCExceptionReporter] ORA-01483: invalid length for DATE or NUMBER bind variable
2011-05-03 19:10:14,414 ERROR [org.hibernate.util.JDBCExceptionReporter] ORA-01483: invalid length for DATE or NUMBER bind variable
2011-05-03 19:10:14,414 ERROR [org.hibernate.event.def.AbstractFlushingEventListener] Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:254)
这里提到的两个报错信息汇总如下:
ORA-01461: can bind a LONG value only for insert into a LONG column
ORA-01483: invalid length for DATE or NUMBER bind variable
由于这个报错的发生,导致数据出现了异常。业务数据的恢复耗费了很大的精力。
2.问题分析
MOS上记录了这个报错信息的基本原因和处理方法。
参见MOS文章“OERR: ORA 1461 can bind a LONG value only for insert into a LONG column [ID 18864.1]”,内容如下。
Error: ORA 1461
Text: can bind a LONG value only for insert into a LONG column
-------------------------------------------------------------------------------
Cause: An attempt was made to insert a value from a LONG datatype into
another datatype.
This is not allowed.
Action: Do not try to insert LONG datatypes into other types of columns.
从报错信息上看,貌似是由于插入的值过大导致的报错。
不过从插入的信息和表结构定义进行分析,初步排除了这种可能性。
3.进一步的问题现象
从测试环境上进行了反复测试,现象如下:
在串行执行下,应用程序运行正确无误,没有出现如上报错。
然而,在并行执行的条件下,便“偶尔”会出现这个问题。
从此现象分析,便可以排除故障是由于数据本身问题导致的。
4.问题原因
经过尝试和测试。最终确认了此问题是由于应用程序中使用的驱动程序与Oracle服务器端的版本不一致导致的。
5.处理方法
将服务器端的驱动程序(ojdbc14.jar)替换应用程序中的文件。
数据库服务器上驱动程序位置如下。
ora10g@secdb /home/oracle$ cd $ORACLE_HOME/jdbc/lib
ora10g@secdb /oracle/ora10gR2/product/10.2.0/db_2/jdbc/lib$ ls -ltr
total 13M
-rw-r----- 1 oracle oinstall 1.6M Jun 22 2005 nls_charset12.jar
-rw-r----- 1 oracle oinstall 1.6M Jun 22 2005 classes12.jar
-rw-r----- 1 oracle oinstall 1.6M Jun 22 2005 classes12.zip
-rw-r----- 1 oracle oinstall 1.6M Jun 22 2005 classes12dms.jar
-rw-r----- 1 oracle oinstall 1.5M Jun 22 2005 ojdbc14.jar
-rw-r----- 1 oracle oinstall 1.5M Jun 22 2005 ojdbc14dms.jar
-rw-r----- 1 oracle oinstall 1.9M Jun 22 2005 ojdbc14_g.jar
-rw-r----- 1 oracle oinstall 1.9M Jun 22 2005 ojdbc14dms_g.jar
经过反复测试,故障得到了有效处理。
6.小结
从此问题分析和处理过程中我们得到的经验和教训是:需要充分重视应用程序开发与数据库技术结合的重要性!
任何细节上的疏忽都有可能对生产环境产生重大的影响。
Good luck.