2017-05-15 10 views
1

Tomcat 8.5.9でJava 8を使用してOracle 11.2データベースに書き込む際に問題があります。実際には、次のコードはストアドプロシージャへの書き込みには問題ありませんが、データベースに直接書き込むときにエラーが発生します。OraclePreparedStatementを使用してTomcat 8.5.9経由でjava 8からoracle 11.2データベースに書き込みますか?

Context initCtx = new InitialContext(); 
Context envCtx = (Context) initCtx.lookup("java:comp/env"); 
DataSource ds = (DataSource) envCtx.lookup("jdbc/myPool"); 
conn = ds.getConnection(); 

// The following works fine: 
cs = conn.prepareCall("{call my_proc (?,?)}"); 
cs.setString(1, var1); 
cs.registerOutParameter(2, Types.VARCHAR); 
cs.execute(); 
out_var2 = cs.getString(2); 

// The following results in a ClassCastException error: 
sql ="INSERT INTO MY_TABLE1 (my_value1, my_value2) VALUES (?,?)"; 
ps = (OraclePreparedStatement) conn.prepareStatement(sql); 

// The following results in the same error, but is an example of using Oracle extensions for setXXX(): 
sql="INSERT INTO MY_TABLE2 (my_value3, my_value4) VALUES (?,?)"; 
ps = (OraclePreparedStatement) conn.prepareStatement(sql);  
for (ii=0; ii<var100.length; ii++) { 
    ps.setBinaryFloat(3, my_value3[ii]); 
    ps.setBinaryDouble(4, my_value4[ii]); 
    ps.addBatch(); 
} 
ps.executeBatch(); 

エラーはjava.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement cannot be cast to oracle.jdbc.OraclePreparedStatementです。

私は最近、GlassFishからTomcatに切り替えました。 Glassfishのために働いていた前のコードはでした:

OracleDataSource ods = ds.unwrap(OracleDataSource.class); 
OracleConnection conn = (OracleConnection) ods.getConnection(); 
conn = ds.getConnection(); 
sql_a ="INSERT INTO MY_TABLE (my_value1, my_value2) VALUES (?,?)"; 
ps_a = (OraclePreparedStatement) conn.prepareStatement(sql_a); 

が、それは誤り、Tomcatでjava.lang.NullPointerExceptionを与えます。

私はガイドとして、以下のリンクを使用して、私のTomcatのファイルを設定した:

https://tomcat.apache.org/tomcat-8.5-doc/jndi-datasource-examples-howto.html

特にOracle 8i, 9i, & 10g(コンテキストコンフィギュレーションとweb.xml)のセクション。

ストアドプロシージャに書き込むときに上記のコードをそのまま使用できるようにしながら、データベースに直接書き込むときにTomcatエラーをどのように排除することができますか?

+0

準備済みの文を「OraclePreparedStatement」としてキャストする必要がありますか?あなたが 'PreparedStatement'を持っていれば十分ではありませんか? – DanielBarbarian

+0

ありがとう@DanielBarbarian、私はOracleの拡張機能、特に 'setXXX()'メソッドを使って、oracle.sqlをバインドしています。型およびオブジェクトを準備されたステートメントに変換します。だから私はこれを動作させる必要があります。元の投稿を更新して例を表示します。 – user46688

+1

'jdbc/myPool'の設定は何ですか?これは、Oracle接続を取得していないか、Oracleドライバを使用していないようです。 – unleashed

答えて

0

これは最善の答えではないかもしれませんが、試行錯誤の結果、OracleConnectionへの接続をアンラップするために1行のコードを追加するだけで済み、すべて正常に動作することがわかりました。

... 
Connection tconn=null; 
OracleConnection conn=null; 
Context initCtx = new InitialContext(); 
Context envCtx = (Context) initCtx.lookup("java:comp/env"); 
DataSource ds = (DataSource) envCtx.lookup("jdbc/myPool"); 
tconn = ds.getConnection(); 
// the following line is needed to unwrap to OracleConnection 
conn= tconn.unwrap(OracleConnection.class); 
tconn.close(); 
... 

私は、代替(おそらくより良い)OracleConnectionのためにTomcatを設定する方法があります確信しているが、私はそれを行うかどうかはわかりません。

1

これは、Tomcatの中で私のためにどのように動作するかです:

(A)//のcontext.xmlでリソースを定義し、webappsの下に置きますMETA-INF/context.xmlに

<Context> 
<Resource name="jdbc/orcldriver_dbcs" auth="Container" 
    type="javax.sql.DataSource" 
    driverClassName="oracle.jdbc.OracleDriver" 
    username="hr" 
    password="hr" 
    url="jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(HOST=myhost)(PORT=1521)(PROTOCOL=tcp))(CONNECT_DATA=(SERVICE_NAME=myorcldbservicename)))" 
/> 
</Context> 

(b)サーブレットでは、以下のようにリソースを参照してください。

ctx = new InitialContext(); 
Context envContext = (Context) ctx.lookup("java:/comp/env"); 

// Look up a data source 
javax.sql.DataSource ds 
      = (javax.sql.DataSource) envContext.lookup ("jdbc/orcldriver_dbcs"); 


// With AutoCloseable, the connection is closed automatically. 
     try (OracleConnection connection = (ds.getConnection()).unwrap(oracle.jdbc.OracleConnection.class)) 
{ 

.... 
doSQLWork(); 
.... 
} 
関連する問題