🌱

Spring BootでJdbcDaoSupportを使ってはいけない

2022/10/13に公開

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;
    // ...
}

JdbcTemplateNamedJdbcTemplateをインジェクションして、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もわざわざ設定しとうない。ということで諦めずに原因を探る。
  • あれ……?このコード、よく見たらJdbcTemplatedataSourceも明示的に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.

https://github.com/spring-projects/spring-framework/blob/main/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcDaoSupport.java

  • starter-jdbcにお任せしてAuto Configureの恩恵にあずかれると思っていたが、こいつは対象外でjavax.sqlのお作法で書かなければいけない。つまり、xmlを書かなければならないということで……。
  • ……extendsしない方向性で書き直すかー……。

というわけで、上記の結論に至ります。

まとめ

モダナイゼーションはやってるとマイナーかつしょうもないところで詰まりがちでつらいっす。

Discussion