Kotlin で JPA エンティティを実装しようと思って調べた結果をまとめた記事です。
まとめ:
-
プロジェクト構成について
-
kotlin-jpa
compiler plugin を適用する -
all-open
compiler plugin を適用し、@Entity
,@Embeddable
,@MappedSuperclass
を対象に設定する
-
-
エンティティ定義について
-
(原則として)
data
class やval
の利用は諦める-
Java で Lombok の
@Data
や@Value
を付与したときと同じような問題がある(参考)
-
-
参考になるリンクとしては:
-
Best Practices and Common Pitfalls of Using JPA (Hibernate) with Kotlin
-
IntelliJ JPA Buddy プラグイン の公式ブログ
-
最後の "Conclusion" 節にまとまっています
-
-
Building web applications with Spring Boot and Kotlin
-
Spring Boot 公式チュートリアル
-
どちらもサンプルコードが付属しているので、具体的にどう実装すれば良いかはそちらを見れば明確です。
一応、自分のサンプルコードもリンクしておきます:
上記以外の情報ソースとしては次のものがあるかと思います:
-
上記 Spring Boot チュートリアルの issues を JPA 関連ワードで検索する
-
JetBrains issue tracker を JPA 関連ワードで検索する
ちなみに、上記したリンク先に書かれいることに反しているとうまく動かないのかと言うと、必ずしもそうではありません。 が、もしあなたが JPA に精通していないのであればそれらに従っておくのが無難かと考えます(問題が発生したとき、何が原因なのか突き止められない可能性があります)。
例えば、次のエンティティは正常に永続化できますが、これは何故動作するのかを説明できるでしょうか(なぜ id
は val
なのに値が変わるのでしょうか)。
@Entity
data class MyData(
@Id
@GeneratedValue
val id :Int? = null,
val name: String,
)
-
JPA 仕様上は許されていません
-
"No methods or persistent instance variables of the entity class may be final." (2.1. The Entity Class)
-
-
val
(final
) の値が変更できるのは、 Hibernate 実装においてリフレクションで値を設定しているからです。-
ただし、 Hibernate プロジェクトは今や JPA にかなり寄り添っているので、 JPA の仕様から反してはいるが Hibernate では合法、とも言えないでしょう。たまたま上手く動いているだけ、とみなすのが正しい認識かと考えます。
こちらの動画でも似たような話題が挙がっていました: