2012-03-09 49 views
0

任何人都知道在我的Java程序中嘗試訪問不同Linux服務器上的Oracle數據庫時可能導致以下RUN TIME錯誤?使用JDBC連接到遠程數據庫的ClassCastException的newbie java錯誤

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

我們可以假設的背景下已經綁定到Oracle數據源?如果是這樣,當你查找的上下文,而不是(數據源),使用(OracleDataSource) – Sean 2012-03-09 04:36:59

回答

0

可能有不止一種方法來解決這個問題,但對上述代碼的以下更改適用於我。這個說法

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

:更換這一說法

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

問題是你定義的變量作爲

CallableStatement cs; 

,然後用

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

鑄造它的CallableStatement是超級接口OracleCallableStatement,你不能給它的孩子施加一個超級接口(你可以做相反的事)。您應該可以將cs更改爲OracleCallableStatement

+0

謝謝twain249,這樣做後,我得到了'conn.prepareCall(語句:'java:230:不兼容的類型的編譯錯誤。發現:java.sql.CallableStatement,required:oracle.jdbc.OracleCallableStatement'。 – ggkmath 2012-03-09 04:17:54

+0

Oracle的JDBC Dev Guide第4-14頁和第4-15頁的鏈接顯示cs被轉換爲CallableStatement(它編譯的很好)。我不確定這是否是問題(或者如何解釋他們的代碼?) – ggkmath 2012-03-09 04:25:37

+0

嘗試在該行添加一個強制轉換到OracleCallableStatement。 – twain249 2012-03-09 04:29:33

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上閱讀更多關於陳述包裝的信息。

+0

Thanks Perception。我從上面的鏈接借用了這個特定版本的Oracle,所以也許我不需要GlassFish (? )。如何消除Oracle的具體情況?我應該用CallableStatement替換OracleCallableStatement還是其他需要? – ggkmath 2012-03-09 04:42:31

+0

看起來您需要執行轉換,才能使用'getCursor()'方法。這很好,只要確保像我在代碼示例('conn = ds.getConnection(conn);')中展示的那樣展開連接。 – Perception 2012-03-09 04:48:22

+0

上面的解包行導致這個相同的(unwrap)行出現編譯錯誤:'找不到符號,符號:方法getConnection(java.sql.Connection),位置:接口javax.sql.DataSource'。我導入了'java.sql。*'和'javax.sql.DataSource'。 – ggkmath 2012-03-09 04:59:25

相關問題