blog/content/posts/2023-11-23/index.md

3.3 KiB

author draft categories date tags keywords title relpermalink url decription
usbharu true
技術
2023-11-23T15:39:49+09:00
Kotlin
Spring Data
Spring Data JDBC
Spring Framework
Kotlin
Spring Data
Spring Data JDBC
Spring Framework
Spring Data JDBCでKotlinのvalue classを使うのはめちゃくちゃめんどくさい posts/2023-11-23/ posts/2023-11-23/ Spring Data JDBCでKotlinのvalue classを使うのはめちゃくちゃめんどくさい

はじめに

どうしても Spring Data JDBC で value class を使いたかったので調査しました。現状なんとか動くレベルなので本番で使うのは辞めといたほうが良さそうです。

Kotlin のvalue classはインライン展開されるからうんぬんは Spring Framework の前では無意味です。

とりあえず動くようにしたリポジトリです。

https://github.com/usbharu/kotlin-data-class-spring-data-jdbc

環境

  • Spring Boot 3.2.0-SNAPSHOT

  • Java 17

  • Kotlin 1.9.20

  • Spring Boot Starter Data JDBC

    よって記事執筆時には再現出来たことが手元では再現できない可能性があります。

解説?

data class

Private である必要はないと思いますがプライマリコンストラクターを使わずにファクトリメソッドでインスタンスを生成させています。

というのも、value class を含ませた data class の場合何故かDefaultConstructorMarkerなるものが勝手にコンストラクタに追加され、Spring Framework がインスタンスの生成に失敗します。(正確にはインスタンスのファクトリの生成に失敗する)

このDefaultConstructorMarkerというパラメータ、本当にデフォルトのコンストラクタのマークのためだけに使われているようで、実装1を読んでも private なコンストラクタが書かれているだけでした。

また、@PersistenceCreatorアノテーションでインスタンスの生成にファクトリメソッドを使用するよう指定しています。

@Idアノテーションは Spring Data JDBC に識別子を指定します。

@get:JvmNameアノテーションは value class を使用した際、勝手に getter 名を変えられるので強制的に上書きしています。これにより Spring Framework がリフレクションで id を取得することが出来ます。

value class と Converter

こちらもファクトリメソッドでインスタンスを生成させていますが、必要ありません。

Converterは Spring がコンバーター無いぞって言ってきたので追加しました。インライン展開されるとはなんだったのでしょうか…

コンバーターはJdbcConfigurationに登録する必要があるので登録しておきます。

最後に

まだまだ検証しないといけないことがたくさんあるのでそのうちやりたいと思います。 value class のコレクションや findBy に指定したときに安定して動くようになったら実用できそうです。