- PR -

TorqueでのDate型データを取得

1
投稿者投稿内容
TK
常連さん
会議室デビュー日: 2002/08/13
投稿数: 42
投稿日時: 2003-10-03 19:15
お世話になってます。TKです。
現在、Struts1.1 + Torque3.0.1 + Oracle9i+ Tomcatで
アプリケーションを開発中ですが、
TorqueにてDate型のデータを取得ときに問題があり困っています。
たとえば、OracleのテーブルでDate型のカラムに
2003年10月3日の18時50分30秒と入っていたとします。
このテーブルに対して、TorqueのdoSelectメソッドでレコード
を取得すると2003/10/03 00:00:00がデータとして
取得されます。
Torqueを使われてる方々にとってはありきたりの問題かもしれませんが
どのように対処してよいのか教えていただけないでしょうか。
doSelectを修正する必要があるのでしょうか?
Toqueで生成されたクラスのソースを見ていますが、解決策はまだ
みつかっておりません。
よろしくお願いいたします。


TK
常連さん
会議室デビュー日: 2002/08/13
投稿数: 42
投稿日時: 2003-10-03 19:33
TKです。追伸します。
doUpdate,doInsert,sava()メソッドで
Date型のデータをテーブルに入れる場合も
同じく時刻が00:00:00でセットされました・・・



TK
常連さん
会議室デビュー日: 2002/08/13
投稿数: 42
投稿日時: 2003-10-03 19:33
TKです。追伸します。
doUpdate,doInsert,sava()メソッドで
Date型のデータをテーブルに入れる場合も
同じく時刻が00:00:00でセットされました・・・



Kiriko
常連さん
会議室デビュー日: 2003/09/25
投稿数: 25
投稿日時: 2003-10-04 21:57
こんばんは。
Kiriko@Torque使い始めてちょうど1週間です^^;

私の環境はTorque3.1 & Oracle8i 8.1.7ですが、
時刻情報も含めて日付データを正しくSelect, Insert, Update
できています。

実はこの間、torque-userメーリングリストで
いろいろと調べていたところ、
TKさんと同じような問題を抱えている人の記事を見つけました。
http://www.mail-archive.com/torque-user@db.apache.org/msg00489.html
また、Torqueで実際のデータベースアクセスを担当しているVillageコンポーネント
のソースプログラムもざっと読んでみました。
そして、私は次のように理解しました。

[原因]
コード:

Emp emp;
・・・・・・
java.util.Date date = Calendar.getInstance().getTime();
emp.setHiredate(date); 
(*1) - EMP.HIREDATE(データ型はDATE)の値を現在時刻に設定しようとしている
・・・・・・・
emp.save();



アプリケーション開発者が上記の(*1)のように指定した値(例ではjava.util.Dateオブジェクト)を、
VillageコンポーネントがSQL(PreparedStatement)文を生成するときに、
別のクラスのオブジェクトに変換する場合があります。
EMP表のHIREDATE列に現在時刻を設定する場合を例に取ると、
(1)EMP表のHIREDATE列のColumnTypeを
ResultSetMetaData#getColumnType(int column);
を利用してデータベースに問合せます。

(2)ColumnTypeが、java.sql.Types.TIMESTAMPであれば、
アプリケーション開発者が指定した現在時刻(java.util.Date)からjava.sql.Timestampオブジェクト
を生成し、PreparedStatementに設定します。
ColumnTypeがjava.sql.Types.DATEであれば、
java.util.Dateからjava.sql.Dateに変換(*** ここで時刻情報が消える ***)
し、PreparedStatementに設定します。

Oracle8iでは列の型がDATEの場合、ColumnTypeはjava.sql.Types.TIMESTAMPとなります。
Oracle9iの環境がないので確かめていませんが、
ColumnTypeはjava.sql.Types.DATEとなると「想像」します。
そうすると時刻情報が消えて列に登録されます。


[誰が悪いのか?]

私の考えではとりあえず(?)誰も悪くないです。
・Torque責任者は、
「それはTorqueが利用しているVillageコンポーネントの仕様である。」
 と答えるでしょう。
・Villageコンポーネント担当者は、「JDBCドライバがjava.sql.Types.DATEを返すから
 悪いんだ。時刻情報も登録したいなら、java.sql.Types.TIMESTAMPを返すべきだ。」
 と答えるかもしれません。
・JDBCドライバー開発者は、
 「それが仕様です。どうしてTorqueのためにその仕様を変更する必要が
あるのでしょうか?」
 と答えそうです。
・アプリケーション開発者は、「これはTorqueかJDBC Driverのバグです。」と
 答えそうです。でもそうなのでしょうか。
事前に検証していれば気づくレベルの問題である気がしてなりません。


[解決策]

1.Oracle9i環境がないので、「想像」で書きます。
  列のデータ型がTimestamp(Oracle9iからサポート)の場合、
  ColumnTypeはjava.sql.Types.TIMESTAMPを返すのでは?
  と想像することは自然なことです(笑)。
  もしこれが事実ならば、データベースの列のDATE型をTIMESTAMP型に変更すれば、
  Oracle9iでもTorqueを利用できる「かも」しれません。
  あ、Oracle8iにバージョンダウンするというのもありますね^^;

2.次に思い浮かぶのは、Villageコンポーネントを自分用に修正することです。
  http://share.whichever.com/index.php?SCREEN=village
  このURLがVillageコンポーネントのホームページらしく、
  ソースファイルもダウンロードできます。
  また、このファイルをダウンロードして見たところ、
  修正箇所の検討もつきます。
  でも、なぜかあまり気が進みません。
  なぜならば、どのソースのバージョンに修正を加えたらよいのかよくわからないし、
  該当するバージョンのソースファイルがどこにあるのかわからないからです。
  また、修正箇所の検討はつきますが、自信を持って修正するには
  Villageコンポーネントをソースレベルで理解する必要があると思います。

1あるいは2を選択できない場合は、別のデータベースアクセス(ORM Tool)を
検討するしかないと思います。

※TKさんの問題がこのケースかどうかわかりませんし、
 もしそうであったとしても記述した内容に私は責任を持てません。
 私の英語力の無さによって間違って解釈している部分や想像で書いている部分が多いためです。
 TKさん自身が納得する方法で確認してください。

以上です。


[ メッセージ編集済み 編集者: Kiriko 編集日時 2003-10-04 22:02 ]
TK
常連さん
会議室デビュー日: 2002/08/13
投稿数: 42
投稿日時: 2003-10-06 14:39
kirikoさんご返答ありがとうございます。

villageコンポーネントのソースを見てみましたが
おっしゃる通りでした。予想通り、
OracleのカラムをTIMESTAMP型にしたところ、時刻部分の
切り捨ては解決しました。

ありがとうございました。

TK
1

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