最近、コードもDBの設定も同じなのにエラーになるプロジェクトとならないプロジェクトがありました。
なにが原因か調べたところ、JDBCドライバのマッピング定義が関係しているようで、それをまとめていこうと思います。
エラー内容
まずどんなエラーが出ていたかというと、SELECT文でDBから値を取ってきたところで型の不整合でClassCastExceptionになるという内容でした。具体的には、current_timestamp()で取り出した値の型が以下の様になってました。
上手くいっている方:LocalDateTime
上手くいってない方:Timestamp
原因究明
色々調べていく中で、マッピング定義というものを見つけました。 マッピング定義とは、DB上のデータの型をJava上で扱うときにJavaに合わせた型に変換する決まりのことです。例えば↓の様なのがあります。
DB | Java |
---|---|
CHAR | String |
bigint | long |
みたいな感じです。
じゃあ、何故取り出し方がそれぞれのプロジェクトで違ってしまっていたのでしょうか。
JDBCドライブ設定
調べていくと、どうやらJDBCドライバによって若干マッピング定義が違うことがあるそうです。2つのプロジェクトを見比べると、確かにDB設定のファイルで記述されているJDBCドライバが違いました。
上手くいっている方:MySQL
上手くいってない方:mariaDB
実際にJDBCドライバを上手くいっている方に合わせてみると、ちゃんとLocalDateTimeで値を取ってくることが出来ました。
こんな所で結構変わるんですねぇ。。
まとめ
SQLで取ってくる値が想定と違う場合、JDBCドライバを見直してみるのも重要かもしれませんね。特別な制約が無ければ、取ってきた値をJava上で変換してあげた方が楽なんでしょうが。
また、今回のプロジェクトではmariaDBを使ってたんですが、ドライバはmySQLの物を使用しました。問題なく動作しています。
mariaDBとmySQLは互換性があるそうなので大丈夫らしいんですが、ドライバをいじるときはちゃんと動作するかは要確認ですね。