使用spring后发现和oracle的驱动有了不解之缘,最初是spring的jdbc存取oracle的clob字段,出现
org.springframework.transaction.TransactionSystemException: Could not roll back JDBC transaction; nested exception is java.sql.SQLException: Io 异常: Software caused connection abort: socket write error
问了Juergen Hoeller几次,也没有知道原因所在。只有加入了hibernate解决此问题,hibernate如何解决oracle的clob字段,看我以前的帖子(http://blogger.org.cn/blog/more.asp?name=hongrui&id=1171)。
后来看到agilejava也遇到这类问题,原来是ojdbc14.jar驱动的问题,改为9.2.0.5.0,一切OK了。相关blog(http://agilejava.blogbus.com/logs/2005/02/1031034.html)
因为现在大量用到存储过程,打算使用spring的StoredProcedure 进行操作,发现运行到SQLErrorCodes loaded: [DB2, HSQL, MS-SQL, MySQL, Oracle, Informix, PostgreSQL, Sybase] 就停了,没有办法,问了Thomas Risberg,他说程序没有错误,我当时就晕了,后来听说虎子做过类似的工作,代码给虎子看,也说没错,而且在它那里运行正常,我生气了。听从他的建议,加入spring源码调试,也不知道问题所在。认为是数据库的问题,换了台数据库还是不行。最后把防火墙撤掉,让虎子直接访问数据库,他那里一切正常。问题明朗了,数据库一样的,代码一样的,唯一不同的是jdk和oracle驱动,他的jdk1.425,我得1.421,差别不大,那就是驱动的问题,我换了以前用的ojdbc14.jar,现在用的版本10.1.0.2.0,换到9.0.2.0.0,一切OK,此时,我已经出离愤怒了,建议oracle驱动最好是自己命名,把文件名加上版本信息,要不会死人的。
下面是我作测试的PLSQL代码
CREATE OR REPLACE package chapter_13 as
TYPE rs IS REF CURSOR ;
procedure founder(oFields out rs);
end;
/CREATE OR REPLACE package body chapter_13 as
PROCEDURE founder(oFields out rs) IS
BEGIN
open oFields for
select * from dept;
END founder;
end;
java代码
package springtest;
import java.sql.*;
import java.util.*;
import javax.sql.*;
import oracle.jdbc.driver.OracleTypes;
import org.springframework.jdbc.core.*;
import org.springframework.jdbc.datasource.*;
import org.springframework.jdbc.object.*;
public class TestDao {
public static void main(String[] args) throws Exception {
new TestDao().execute();
}
public void execute() throws Exception {
DataSource ds = new DriverManagerDataSource(
"oracle.jdbc.driver.OracleDriver",
"jdbc:oracle:thin:@localhost:1521:mydb",
"scott", "tiger");
DemoStoredProcedure proc = new DemoStoredProcedure(ds);
Map params = new HashMap();
proc.execute(params);
}
private class DemoStoredProcedure extends StoredProcedure {
public static final String SQL = "chapter_13.founder";
public DemoStoredProcedure(DataSource ds) {
setDataSource(ds);
setSql(SQL);
setFunction(false);
declareParameter(
new SqlOutParameter(
"obrief", OracleTypes.CURSOR, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) throws
SQLException {
System.out.println(rs.getString(1));
return rs.getString(1);
}
}
));
compile();
}
}