最近将一个基于tomcat通过JNDI维护的数据库连接池,转移到SpringBean中通过org.apache.commons.dbcp.BasicDataSource来进行连接池管理。
一切都很顺利,但是在最后执行oracle存储过程的时候,报了一个很奇怪的错误:
java.lang.ClassCastException: org.apache.commons.dbcp.PoolableConnection cannot be cast to oracle.jdbc.OracleConnection
at oracle.sql.ArrayDescriptor.createDescriptor(ArrayDescriptor.java:108)
报错的位置的代码是这样写的:
Connection connection = statement.getConnection().getMetaData().getConnection();
ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor("MYTABLETYPE", connection);
就是在这个createDescriptor函数里面抛出的异常。
首先百度了一下,有几种可能:
1、java调用orace存储过程,传入参数类型为数组,需要在Oracle中自定义一个数组类型,除非数据库上没有自定义。
2、从错误的字面意思来看,貌似是传入的类型不是原始的OracleConnection,因此不能完成创建。
于是比较纳闷.getMetaData().getConnection();获取到的应该就是原始连接啊。
既然提示中说传入的是org.apache.commons.dbcp.PoolableConnection 那么我们不妨查查org.apache.commons.dbcp.PoolableConnection的接口文档。
将connection转为org.apache.commons.dbcp.PoolableConnection 看看里面都有什么。
在接口文档中看到org.apache.commons.dbcp.PoolableConnection 有一个方法getDelegate()
http://www.docjar.com/docs/api/org/apache/commons/dbcp/DelegatingConnection.html#getDelegate
描述为Returns my underlying Connection
应该是获取原始代理连接的,修改后测试了一下,果然可以查询存储过程了!
另外在对getDelegate的研究过程中发现几篇有价值的帖子,一并收藏如下:
http://pxhoo.blog.163.com/blog/static/4939970200891494022919/
http://hi.baidu.com/lffsonic/blog/item/4c3b0195eb7a1315d21b70ad.html