1

JUnit テスト ケースの 1 つで H2 データベース テーブルを作成するために使用している次の DDL を検討してください。

CREATE TABLE "CONFIG_INFO" 
   (    "ID" VARCHAR2(12 BYTE), 
        "RUN_DATE" DATE, 
   );

私が単体テストを書いているクラスは、このテーブルにレコードを挿入しようとします。レコードを挿入するために次のクエリが実行されていることがわかります。

insert into CONFIG_INFO(ID,RUN_DATE) values (?,?) 

ただし、挿入は次の例外で失敗します。

org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [insert into CONFIG_INFO(ID,RUN_DATE) values (?,?)]; Cannot parse "DATE" constant "31-Jan-20"; 

調べてみたところ、この問題は通常、日付の一部として時間要素がある場合に発生することがわかりました。ただし、コードをデバッグすると、上記のエラー メッセージからもわかるように、Java コードがタイムスタンプ コンポーネントなしで「31-Jan-20」を渡していることがわかります。

このエラーを解決するにはどうすればよいですか?

4

2 に答える 2

2

java.time

最善の解決策は、ダム文字列ではなくスマート オブジェクトを使用してデータベースと値を交換することです。具体的には、最新のjava.timeクラスを使用してください。

入力では、すべて大文字の月名を使用しています。これは、英語のローカリゼーションには準拠していません。少なくとも、米国または英国の英語ではそうではありません。したがって、すべての大文字を許容DateTimeFormatterBuilderする a を取得するために使用する必要があります。DateTimeFormatter

DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern( "dd-MMM-uu" ) ;
DateTimeFormatter formatter = builder.toFormatter() ;

入力文字列を解析します。

String input = "31-JAN-20" ;
LocalDate localDate = LocalDate.parse( input , formatter ) ;

誤入力時のトラップDateTimeParseException

JDBC 4.2 以降に準拠した JDBC ドライバーを使用してデータベースに渡します。

myPreparedStatement.setObject( … , LocalDate ) ;

取得します。

LocalDate localDate = myResultSet.getObject( … , LocalDate.class ) ;

ヒント:日時値をテキストとして交換するためのISO 8601標準形式について、データの公開者を教育してください。

于 2020-04-13T15:36:44.023 に答える