3.3 KiB
author | draft | categories | date | tags | keywords | title | relpermalink | url | decription | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
usbharu | true |
|
2023-11-23T15:39:49+09:00 |
|
|
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 に指定したときに安定して動くようになったら実用できそうです。