🌱
Spring BootでJdbcDaoSupportを使ってはいけない
Spring Framework => Spring Bootへの移行をしてるときにハマったことについての備忘録みたいな記事です。
zennは結構キラキラしてるイメージが強いのですが、こういう泥臭く古の技術と向き合ってる人もいるよ、と、同じような感じでやってる人の励みになれば幸いです。
想定読者
- レガシーと戦ってる人
- Spring Boot移行に手を付ける、もしくは付けざるを得ない人
- そういう人の変な苦労を見たい奇特な人
環境
- Java 17
- Spring Boot 2.7.4
結論
- 大人しく
spring-boot-starter-jdbc
を依存関係から消して、Spring Data JPAとかjOOQとか使いましょう。JdbcTemplateも悪すぎるわけではないのですが、いかんせん生のSQLを文字列でゴリゴリはしんどいです。豊富なライブラリの恩恵にあずかりましょう。 - 生のSQLをコード上に書くのを強制させたいとか、RowMapper以外信用ならんとか、どうしても動的にSQLゴリゴリ変えなきゃならんねんみたいな理由で利用する場合は、せめて以下のようにSpring BootのAuto Configureの恩恵にあずかれるようにしましょう。
- 「xmlに設定を集約させた方がいい」という環境の場合は……がんばれ!
やったこと
@Repository
public class HogeHogeRepository extends JdbcDaoSupport {
// ...
}
Spring Bootでこういうのを見つけたら
spring.datasource.url=${url}
spring.datasource.username=${username}
# ... etc
}
Pleiadesの作者の方に感謝しながらプロパティ一覧と睨めっこしつつ、application.properties
にこんな感じで書くか、環境変数を使ってDB接続の設定を書いて、
@Repository
public class HogeHogeRepository extends JdbcDaoSupport {
@Autowired
private JdbcTemplate jdbcTemplate;
// ...
}
JdbcTemplate
かNamedJdbcTemplate
をインジェクションして、applicationContext.xml
等からdatasourceの設定を追い出します。
経緯とか調査とか
- もともとのコード(Spring 5.x)にあったデータベースアクセス周りのコードを移植しようとしたときに発生
- とりあえずEclipseの実行時変数に必要なパラメータ突っ込んで雑に起動
Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: 'dataSource' or 'jdbcTemplate'
- なんか違うんだろうなー、実行時変数だと確認面倒だから
application.properties
に突っ込んで値が正しそうだったら置き場所変えてみるか => 変わらん。 - 嫌じゃ嫌じゃ、bootでapplicationContext.xmlもdataSourceのBeanもわざわざ設定しとうない。ということで諦めずに原因を探る。
- あれ……?このコード、よく見たら
JdbcTemplate
もdataSource
も明示的にDIしてない……? -
extends JdbcDaoSupport
しとるやんけ!
- <p>Requires a {@link javax.sql.DataSource} to be set, providing a
- {@link org.springframework.jdbc.core.JdbcTemplate} based on it to
- subclasses through the {@link #getJdbcTemplate()} method.
- starter-jdbcにお任せしてAuto Configureの恩恵にあずかれると思っていたが、こいつは対象外でjavax.sqlのお作法で書かなければいけない。つまり、xmlを書かなければならないということで……。
- ……extendsしない方向性で書き直すかー……。
というわけで、上記の結論に至ります。
まとめ
モダナイゼーションはやってるとマイナーかつしょうもないところで詰まりがちでつらいっす。
Discussion