SpringBoot2.7とexposedとh2の組み合わせでorg.h2.jdbc.JdbcSQLSyntaxErrorException
マイクロサービス化の弊害ってどんなものがありますでしょうか。
小回りが利いて便利なマイクロサービスですが、自由度が高すぎるために浮いてしまっているモジュールが出てくるなんてことありますよね。
主力のサービスモジュールは、利用するプログラム言語やライブラリが統一されているけど、小規模なモジュールだけ冒険して別の言語やライブラリが使われていたりとか・・・。
新しいものを使ってみようという試みはわかるのですが、小さなモジュールだけにライブラリのバージョンアップが後手後手になるなんてよくありますよね。
今回は、SpringBoot のアップグレードをしたら exposed 周りでエラーが出たので対応してみました。
Kotlin Exposedとは
Kotlin Exposed は、Kotlin で書かれた軽量で効率的な SQL ライブラリ。
ORM(Object-Relational Mapping)フレームワークとしても機能し、データベーステーブルと Kotlin クラスをマッピングするものです。
要は Kotlin ベースの OR マッパーなのですが、特別使い勝手がいいとは思えなく、枯れた Java のライブラリでいいじゃんって話なのですけどね。
・Hibernate
・MyBatis
・JPA
・JOOQ(Java Object Oriented Querying)
エラー発生の状況
今回発生したエラー時の、各種ライブラリのバージョンは下記の通り。
ライブラリ | バージョン |
---|---|
SpringBoot | 2.7.8 |
kotlin | 1.6.21 |
exposed | 0.11.2 |
h2 | 1.4.200 |
「全体的に古い」って言われるかもしれませんが、なかなかライブラリアップデートの機会がなくて、古いまま残り続けているシステムって多いですよね。
もちろん、先駆者がその後もメンテナンスをするとは限らず、残された者や新しくジョインした人が任されることも珍しくありません。
完全にサポートが切れる前に、脆弱性のリスクが回避できるように前向きに取り組んでいきましょう。
エラー発生の内容
今回発生したエラーは、SpringBoot と h2、そして exposed の絡みです。
UT(ユニットテスト)で h2 にデータ投入する際に出たエラー。
org.jetbrains.exposed.exceptions.ExposedSQLException: org.h2.jdbc.JdbcSQLSyntaxErrorException: 列 "xxxxxx" が見つかりません
Column "xxxxxx" not found; SQL statement:
INSERT INTO XXXXXX ("xxxxxx", "yyyyyy", "zzzzzz") VALUES (?, ?, ?) [42122-200]
SQL: [Failed on expanding args for INSERT: org.jetbrains.exposed.sql.statements.InsertStatement@xxxxxx]
SpringBoot 2.6 系の時は問題ありませんでした。
そもそも、SpringBoot 2.7 では h2 の 2.1 を使えって話なのですが、マイグレーションツールの兼ね合いで 1.4 系に据え置き。
そのマイグレーションツールも MySQL のバージョンの影響を最近まで受けていたのですよね。
色々な条件は絡み合いますが、最低限、エラーが回避できる状態まで持っていきましょう。
exposedのバージョン
h2 が一番怪しいのですが、マイグレーションツールとの絡みで動かしたくないので、exposed のバージョンから調査します。
うーん、0.11.2 なんてリリースタグに存在しない。
かろうじて Change Log には存在するので、そこから追っていきつつ、ライブラリのバージョンを変更していきますか。
ってことで、エラーが回避されたのがバージョン「0.14.1」でした。
一番上の変更点で対応された感じでしょうか。
Fixed support for H2 1.4.198+ (CVE-2018-10054)
LazySizedCollection.limit() produce StackOverflowError exception
Explicitly specify constraint name in create table statement
0.14 系の最新バージョンでもいいかもしれませんが、この後は 0.21 系が控え、最新は 0.46 系となかなか遠いですね。
メジャーバージョンも変わる気配がないので、どちらかというとバージョンに追従するよりは exposed 離脱の方が可能性は高いかも・・・。
まとめ
exposed のライブラリアップデートで h2 との絡みのエラーを回避しました。
個人的には同じものを使っていってノウハウを貯めていくのが好きですが、新しいものや経験のないものを使ってみるという好奇心もエンジニアには必要。
ただ長期のプロジェクトになればなるほど、知見のある人が少なくなっていくという現実はあるわけで、同じような問題は今後も起こり得るでしょう。
できる限り、バージョンアップはこまめにしておきたいですね。
python 好きな人が広めたのか、社内全体のプロジェクトを Bazaar でバージョン管理させられた時を思い出す。Git でいいのになって思っていたけど、それは今だから言えることなのかな。