- PR -

JDBC接続方法違いでエラーとなる。

投稿者投稿内容
S38
会議室デビュー日: 2003/07/07
投稿数: 10
投稿日時: 2003-09-05 12:04
はじめて投稿させていただきます。
JAVA,WEB開発初心者です。

同一テーブルでBLOB型(データ型)を含むデータの格納時、DB接続方法の違いでエラーとなってしまいます。
1)class.forNameクラスでDB接続した場合、OK
2)データソースを活用してDB接続した場合、NG(エラーログ参照)

ちなみに、同一テーブルでBLOB型を含まないデータの格納時、
(CHAR、DATE、VARCHAR2型)どちらのDB接続でもOKです。

私としては、2)の方法を採用したいのですが・・・
何が悪いのか、ご存知の方がいましたら教えて下さい。


環境:
WinXP
jdk1.4.1_04
struts1.1
tomcat4.1.24
oracle8.1.7

それぞれの接続方法のソース
1)class.forNameクラス
Class.forName("oracle.jdbc.driver.OracleDriver");
connection=DriverManager.getConnection("jdbc:oracle:thin:@172.0.0.1:1521:TEST","USR","PASS");

2)データソースを活用
InitialContext ic;
DataSource ds;
ic = new InitialContext();
ds = (DataSource) ic.lookup("java:comp/env/jdbc/TEST");
connection = ds.getConnection();
statement = connection.createStatement();

・Tomcat(server.xml)
<Context path="/sample" reloadable="true" docBase="C:\eclipse\workspace\sample"
workDir="C:\eclipse\workspace\sample\work\org\apache\jsp" >
<Resource name="jdbc/TEST" auth="Container"
type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/TEST">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>username</name>
<value>USR</value>
</parameter>
<parameter>
<name>password</name>
<value>PASS</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>oracle.jdbc.driver.OracleDriver</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:oracle:thin:@172.0.0.1:1521:TEST</value>
</parameter>
</ResourceParams>
</Context>

・エラーログ
HTTP Status 500 -
--------------------------------------------------------------------------------
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException
at org.apache.struts.action.RequestProcessor.processException(RequestProcessor.java:545)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:486)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274)
    :
    省略
    :
root cause
java.lang.ClassCastException
at db_operation.Coracle.bin_insert2(Coracle.java:149)
at action.first.InsertAction.execute(InsertAction.java:55)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484)
    以下省略

長くなってすいません。
よろしくお願いいたします。
S38
会議室デビュー日: 2003/07/07
投稿数: 10
投稿日時: 2003-09-08 14:02
S38です。
もう少し情報を追加させていただきます。
よろしくお願い致します。

以下、作成ソースです。
package db_operation;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;

import java.sql.DriverManager; /*<-- Class.forName接続時、設定 */
/*<-- データソース活用の場合、設定無し*/
import java.sql.ResultSet;
import java.sql.Statement;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import javax.swing.JFrame;
import oracle.jdbc.driver.OracleResultSet;
import oracle.sql.BLOB;

public class Coracle {

private String driver=null;
private String url=null;
private String user=null;
private String password=null;
private Statement statement=null;
private ResultSet resultset=null;
private Connection connection=null;
public byte b[] = new byte[4096];
public static JFrame frame;

synchronized public void bin_insert2(String name,String address) throws Exception{

/*( ↓ class.forNameクラスの接続 コメント ↓ )
Class.forName("oracle.jdbc.driver.OracleDriver");
connection=DriverManager.getConnection("jdbc:oracle:thin:@172.0.0.1:1521:TEST","USER","PASS");
    */

InitialContext ic;
DataSource ds;
ic = new InitialContext();
ds = (DataSource) ic.lookup("java:comp/env/jdbc/TEST");
connection = ds.getConnection();
connection.setAutoCommit(false);

statement = connection.createStatement();
statement.execute("insert into pdf_bin (name,address,blob_col) values     ('"+name+"','"+address+"',empty_blob())");

resultset = statement.executeQuery("select blob_col from pdf_bin where     name = '"+name+"' for update");
resultset.next();

------- ココでエラーとなります。(Coracle.java:149)--------
    ↓↓↓↓↓
BLOB blob = ((OracleResultSet)resultset).getBLOB("blob_col");
------------------------ -----------------------------------
OutputStream out = blob.getBinaryOutputStream();

int size = blob.getBufferSize();
byte [] buff = new byte[size];
int len = -1;

FileInputStream in = new FileInputStream(address);
while((len = in.read(buff)) != -1){
out.write(buff,0,len);
}
out.close();
in.close();
connection.commit();
connection.setAutoCommit(true);
resultset.close();
statement.close();
connection.close();
}

どうしてエラーになるか、さっぱり分かりません。
よろしくお願い致します。
ニシトミ
ベテラン
会議室デビュー日: 2003/04/24
投稿数: 76
お住まい・勤務地: 千葉・東京
投稿日時: 2003-09-08 14:27
BLOB型については
良く知らないのですが
ClassCastExceptionですので
明示的にBLOBでキャストしてみてはいかがでしょうか?

BLOB blob = (BLOB)((OracleResultSet)resultset).getBLOB("blob_col");

エラーでたら申し訳ありません。
S38
会議室デビュー日: 2003/07/07
投稿数: 10
投稿日時: 2003-09-08 14:48
ニシトミさん返答ありがとうございます!
S38です。
早速、明示的にBLOBでキャストしてみましたが
同じ結果になってしまいました。(ClassCastException)

たいへん申し訳ございませんが、
引き続きよろしくお願い致します。
ニシトミ
ベテラン
会議室デビュー日: 2003/04/24
投稿数: 76
お住まい・勤務地: 千葉・東京
投稿日時: 2003-09-08 14:53
解った。

ResultSetをOracleResultSetでキャストしてるからだ

多分そうです
適当なことを言ってるかもしれません。

---編集---
全く根拠が無いです。
嘘書いてしまいました。

[ メッセージ編集済み 編集者: ニシトミ 編集日時 2003-09-08 15:20 ]
藍空
常連さん
会議室デビュー日: 2003/06/24
投稿数: 49
投稿日時: 2003-09-08 15:04
例えば、

BLOB blob = ((OracleResultSet)resultset).getBLOB("blob_col");
OutputStream out = blob.getBinaryOutputStream();



Blob blob = resultset.getBlob("blob_col");
OutputStream out = ((BLOB)blob).getBinaryOutputStream();

にしてみてはいかがでしょう?
# ダメかな?
R-55
常連さん
会議室デビュー日: 2003/03/13
投稿数: 29
投稿日時: 2003-09-08 15:27
普通に

Blob blob = resultset.getBlob("blob_col");
OutputStream out = blob.getBinaryStream();

ではだめですか?


追加:
oracle.sql.BLOBでしたか・・・。
ここもキャストしないとだめですね。

藍空さんのでよさそうです。



[ メッセージ編集済み 編集者: R-55 編集日時 2003-09-08 15:35 ]
S38
会議室デビュー日: 2003/07/07
投稿数: 10
投稿日時: 2003-09-08 15:30
ニシトミさん、藍空さん、R−55さん返信ありがとうございます。
S38です。
resultsetにgetBlobメソッドがないんですけれども、
OracleResultSetクラスにgetBLOBメソッドがあります。
(なんでClass.forNameクラスで接続するといいのかな?)

誠に申し訳ございませんが、引き続きお願い致します。

スキルアップ/キャリアアップ(JOB@IT)