From 6ff49c81968da584c2786f2d14480b63b6346051 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 23 Nov 2023 16:04:52 +0900 Subject: [PATCH] =?UTF-8?q?2023-11-23=E3=81=AE=E8=A8=98=E4=BA=8B=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/posts/2023-11-23/index.md | 71 +++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 content/posts/2023-11-23/index.md diff --git a/content/posts/2023-11-23/index.md b/content/posts/2023-11-23/index.md new file mode 100644 index 0000000..f804495 --- /dev/null +++ b/content/posts/2023-11-23/index.md @@ -0,0 +1,71 @@ +--- +author: usbharu +draft: true +categories: + - 技術 +date: 2023-11-23T15:39:49+09:00 +tags: + - Kotlin + - Spring Data + - Spring Data JDBC + - Spring Framework +keywords: + - Kotlin + - Spring Data + - Spring Data JDBC + - Spring Framework +title: Spring Data JDBCでKotlinのvalue classを使うのはめちゃくちゃめんどくさい +relpermalink: posts/2023-11-23/ +url: posts/2023-11-23/ +decription: 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](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 に指定したときに安定して動くようになったら実用できそうです。 + +[^1]: https://github.com/JetBrains/kotlin/blob/83383ab9e5a818cd62209d9134c111998c4f1cf3/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/DefaultConstructorMarker.java