使用JDBC连接到远程数据库的ClassCastException的新手java错误

时间:2012-03-09 04:02:42

标签: java jdbc

任何人都知道在我的Java程序中尝试访问其他Linux服务器上的Oracle数据库时可能导致以下RUN TIME错误的原因是什么?

java.lang.ClassCastException : com.sun.gjc.spi.jdbc40.CallableStatementWrapper40 cannot be cast to oracle.jdbc.OracleCallableStatement

我正在关注Oracle的JDBC开发人员指南(http://isu.ifmo.ru/docs/doc112/java.112/e10589.pdf)中第4-14页到第4-15页的讨论/示例。我创建了类似于该示例的东西,它工作正常。然后我开始修改它以获得下面的代码并将GlassFish引入到该过程中,现在我得到了该错误。

这是我的Java代码:

public List<Report> GetReports(String var1, String var1, String var3) throws Exception {
    Connection conn;
    CallableStatement cs;
    ResultSet rset;
    String out1; 

    Context context = new InitialContext();
    DataSource ds = (DataSource)context.lookup("jdbc/myPool");
    conn = ds.getConnection();

    cs = conn.prepareCall( "{call my_proc (?,?,?,?,?)}" );

    cs.setString(1, var1);
    cs.setString(2, var2);
    cs.setString(3, var3);

    cs.registerOutParameter(4, Types.VARCHAR);
    cs.registerOutParameter(5, OracleTypes.CURSOR);

    cs.execute();

    out1 = cs.getString(4); 

    List<Report> userReports = new ArrayList<Report>();

    rset = ((OracleCallableStatement)cs).getCursor(5);
    while ( rset.next() ) {
        Report report = new Report();
        report.col1 = rset.getString("myCol1");
        report.col2 = rset.getString("myCol2");
        userReports.add(report);
    }

    if ( rset != null ) {
        try { rset.close(); } catch ( Exception ex ) {}
        rset = null;
    }

    if ( conn != null ) {
        try { conn.close(); } catch ( Exception ex ) {}
        conn = null;
    }

return userReports;
}

3 个答案:

答案 0 :(得分:1)

GlassFish默认启用名为声明包装的内容。启用此选项后,您的语句,结果集和数据库元数据对象都将包含在“代理”对象中。通常没有问题,因为您只能通过其标准JDBC接口访问这些对象,但如果您需要特定于供应商的功能,那么您将需要采取额外的步骤来通过此“代理”。

Context context = new InitialContext();
DataSource ds = (DataSource)context.lookup("jdbc/myPool");
conn = ds.getConnection();
conn = ds.getConnection(conn); // <-- 'Unwrap' the vendor specific connection

另一方面,看起来你不需要Oracle特定版本的可调用语句,演员可能完全是多余的。

您可以在Oracle Development Guide for Glassfish Server上阅读有关声明包装的更多信息。

答案 1 :(得分:0)

问题是您将变量定义为

CallableStatement cs;

然后将其与

一起投放
rset = ((OracleCallableStatement)cs).getCursor(5);

CallableStatementOracleCallableStatement的超级界面,你不能为它的孩子施加超级界面(你可以这样做)。您应该可以将cs更改为OracleCallableStatement

答案 2 :(得分:0)

解决此问题的方法可能不止一种,但以上代码的以下更改对我有用。替换此声明:

rset = ((OracleCallableStatement)cs).getCursor(5);

发表声明:

rset = (ResultSet) cs.getObject(5);