C3P0连接池获取原始连接

背景

最近在项目中遇到了之前同事埋下的大坑。项目用C3P0连接池,从连接池直接获取的连接在执行oracle的存储过程时,会报java.lang.ClassCastException: com.mchange.v2.c3p0.impl.NewProxyCallableStatement cannot be cast to oracle.jdbc.OracleCallableStatement的错误,于是前人就没有用连接池而是做了个直连来解决这个问题。

解决过程

照常先是各种百度,谷歌报错信息,查到的原因都说是存储过程的游标或者存储过程的自定义参数类型的问题。可是我们需要对接客户的数据库,总不能让客户改存储过程吧。既然直连可以使用,肯定是c3p0封装的问题。查了写资料,可以用到unwrap方法。但是看了下我们这边的代码,发现没有具体实现unwrap方法。

最后查到了可以通过反射在底层的连接上来执行非标准方法的API[1]

原生连接使用

例子中使用C3P0ProxyConnection.RAW_CONNECTION作为参数,也就是在使用到connection的时候才能完成。刚开始看遍项目代码改了几个地方也没成功,最后在网上发现了其他项目用的代码,参考了一下,他们是添加了一个方法,用来处理这个connection,非常巧妙。

public static Connection getRawConnection(Connection con) { return con; }

C3P0ProxyConnection cpCon = (C3P0ProxyConnection) conn; Connection unwrappedCon = null; try { Method rawConnectionMethod = getClass().getMethod("getRawConnection", new Class[] { Connection.class }); unwrappedCon = (Connection) cpCon.rawConnectionOperation(rawConnectionMethod, null, new Object[] { C3P0ProxyConnection.RAW_CONNECTION }); } catch (Exception ex) { //do something }
将以上代码根据项目实际添加到项目中,实现了c3p0获取原生连接,解决了c3p0连接无法调用oracle的procedure的问题。


参考文献

[1] 数据库连接池手册
[2] SOS开源项目源码
[3] c3p0源码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、事务 事务就是一个事情,组成这个事情可能有多个单元,要求这些单元,要么全都成功,要么全都不成功。在开发中,有事...
    野狗子嗷嗷嗷阅读 2,814评论 0 6
  • 本文包括传统JDBC的缺点连接池原理自定义连接池开源数据库连接池DBCP连接池C3P0连接池Tomcat内置连接池...
    廖少少阅读 16,816评论 0 37
  • 1.JDBC介绍1.1 1.1 JDBC介绍 2.JDBC之API2.1 2.1 JDBC之API 3.JDBC例...
    拾壹北阅读 1,208评论 0 7
  • 北风萧瑟陈留渡。放眼望,银飞舞。漫漫无涯遮去路。亭藏乱霭,舟失迷雾,难辨身居处。 绵绵白絮纷眉目,地冻天寒泪凄楚。...
    静铃音阅读 557评论 32 64
  • 形象学是比较文学的一个重要的领域,研究的是“一国文学中所塑造或描述的异国形象”。形象学与比较文学的发轫同步,属于“...
    南方有咸鱼阅读 5,718评论 15 6