Oracle JDBCドライババージョンによる日付型の扱いの違い

元記事最終更新:2010/08/26

概要

Oracle10gになってJDBCドライバの仕様が変わり、OracleのDATE型に対応するJava型が、java.sql.Timestampからjava.sql.Dateへ変更となった。また、Oracle側にTIMESTAMP型が追加となった(従来のDATE型は秒までの精度だが、TIMESTAMPはミリ秒精度)。

このこと自体は、SQLの標準に照らすと妥当な変更であるが、旧来の慣習によってDB設計を行った場合、問題となる場合があるため、備忘録として記述する。

変更内容

JDBCドライバの変更

OracleのDATE型が、java.sql.Date型にマッピングされた(従来はjava.sql.Timestamp)。これにより、OracleのDATE型に格納された時刻部分の情報が、Javaに持ってきたときに削除されることになる。(java.sql.Dateは時刻情報が入らない)

Oracle型「TIMESTAMP」の追加

日付・時刻(ミリ秒精度)を格納できるTIMESTAMP型が追加された。これは、JDBCドライバによってjava.sql.Timestamp型にマップされる。

想定される悪影響

時刻情報の欠落

日付・時刻の情報を格納する前提でDATE型のカラムを用意したにもかかわらず、Javaで時刻情報が取得・更新できない。

回避策

時刻情報を含む項目はTIMESTAMP型で定義する。

この対応が本道。

JDBCをバージョン8互換モードにする

10g以降のJDBCドライバには、バージョン8互換モードが存在する。このモードにおいては、日付型の扱いはOracle8と同様になるため、上記の問題を回避できる。

バージョン8互換モードで動作させるには、Java起動時に、システムプロパティoracle.jdbc.V8Compatibilityに対してtrueを設定する。

java -Doracle.jdbc.V8Compatibility="true" MyApp

バージョン11gでの変更について

(2010/08/26追記)

JDBCドライバ バージョン11gでは、OracleのDATE型もjava.Date.Timestamp型にマッピングされるように変更となった模様。