3

次のコード スニペットに対して、以下のエラーが発生します。

  try {
        cRows = new CachedRowSetImpl();
        while(cRows.next()) 
        {
        MyClass myClass = new MyClass();
        myClass.setPrevDate(cRows.getDate("PREV_DATE")); // In debug mode, the error was throwing when I press Resume from here.
        }
      }

エラー:

Caused by: java.lang.ClassCastException: java.sql.Timestamp cannot be cast to java.sql.Date

データベースでは、列のデータ型はDATEonly です。Timestampがここに来る場所を把握できません。

4

2 に答える 2

5

この問題について調査を行ったところ、役立つリンクがいくつか見つかりました。この DATE と TIMESTAMP の混乱は JDBC ドライバー固有のものであることがわかりました。そして、ほとんどのリンクは-Doracle.jdbc.V8Compatible=true. 私のJBossではこれを設定しrun.bat、問題は解決しました。

  1. https://community.oracle.com/thread/68918?start=0&tstart=0

  2. http://www.coderanch.com/t/90891/JBoss/oracle-jdbc-Compatible-true

  3. https://community.oracle.com/message/3613155

オラクルのドキュメントでは、さまざまなソリューションを共有しています。

  • DATE の代わりに TIMESTAMP を使用するようにテーブルを変更します。これはおそらくめったに可能ではありませんが、可能な場合は最善の解決策です。

  • アプリケーションを変更して、defineColumnType を使用して列を DATE ではなく TIMESTAMP として定義します。これには問題があります。必要でない限り、defineColumnType を使用したくないからです (defineColumnType とは何ですか? を参照してください)。

  • getObject ではなく getTimestamp を使用するようにアプリケーションを変更します。可能であればこれは良い解決策ですが、多くのアプリケーションには getObject に依存する汎用コードが含まれているため、常に可能であるとは限りません。

  • V8Compatible 接続プロパティを設定します。これにより、JDBC ドライバーは新しいマッピングではなく古いマッピングを使用するようになります。このフラグは、接続プロパティまたはシステム プロパティとして設定できます。DriverManager.getConnection または OracleDataSource.setConnectionProperties に渡される java.util.Properties オブジェクトに接続プロパティを追加して、接続プロパティを設定します。システム プロパティを設定するには、Java コマンド ラインに -D オプションを含めます。

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

リンクは次のとおりです。 http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-faq-090281.html#08_00

于 2014-09-18T14:27:02.523 に答える
5

廃止:

フィールドに使用java.util.Dateします。 java.sql.Timestampそれの直接のサブクラスです。java.sql.Dateそのまま - 時間部分を取り除きます。Java データベース ドライバが DATE を Timestamp と見なす理由は少し奇妙です。データベースのベンダーは?長さなどの指定はありますか?本当に日付だけが保存されますか?


調査済み:

私はCachedRowSetImpl.javaを調べました.OracleのドキュメントとOracleはすべてうまくいきます(java.sql.Date、java.sql.Time、java.sql.Timestamp変換可能)。CachedRowSetImpl は単純に DATE のオブジェクト (および getObject は高解像度のタイムスタンプを時間と共に返す可能性が高い) を java.sql.Date にキャストしますが、これは誤りです。したがって、この太陽のクラスをオーバーライドまたは置換します。

      /*
       * The object coming back from the db could be
       * a date, a timestamp, or a char field variety.
       * If it's a date type return it, a timestamp
       * we turn into a long and then into a date,
       * char strings we try to parse. Yuck.
       */
       switch (RowSetMD.getColumnType(columnIndex)) {
           case java.sql.Types.DATE: {
               long sec = ((java.sql.Date)value).getTime();
               return new java.sql.Date(sec);
       }
于 2014-09-17T14:28:45.023 に答える