任何人都知道在我的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;
}
答案 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);
CallableStatement
是OracleCallableStatement
的超级界面,你不能为它的孩子施加超级界面(你可以这样做)。您应该可以将cs
更改为OracleCallableStatement
。
答案 2 :(得分:0)
解决此问题的方法可能不止一种,但以上代码的以下更改对我有用。替换此声明:
rset = ((OracleCallableStatement)cs).getCursor(5);
发表声明:
rset = (ResultSet) cs.getObject(5);