Kotlin で JPA エンティティクラスを定義する
   2 min read

Kotlin で JPA エンティティを実装しようと思って調べた結果をまとめた記事です。

まとめ:

  • プロジェクト構成について

    • kotlin-jpa compiler plugin を適用する

    • all-open compiler plugin を適用し、 @Entity, @Embeddable, @MappedSuperclass を対象に設定する

  • エンティティ定義について

    • (原則として) data class や val の利用は諦める

      • Java で Lombok の @Data@Value を付与したときと同じような問題がある(参考)

参考になるリンクとしては:

どちらもサンプルコードが付属しているので、具体的にどう実装すれば良いかはそちらを見れば明確です。

一応、自分のサンプルコードもリンクしておきます:

上記以外の情報ソースとしては次のものがあるかと思います:

ちなみに、上記したリンク先に書かれいることに反しているとうまく動かないのかと言うと、必ずしもそうではありません。 が、もしあなたが JPA に精通していないのであればそれらに従っておくのが無難かと考えます(問題が発生したとき、何が原因なのか突き止められない可能性があります)。

例えば、次のエンティティは正常に永続化できますが、これは何故動作するのかを説明できるでしょうか(なぜ idval なのに値が変わるのでしょうか)。

@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 実装においてリフレクションで値を設定しているからです。

    • https://stackoverflow.com/a/3683453/4506703

    • ただし、 Hibernate プロジェクトは今や JPA にかなり寄り添っているので、 JPA の仕様から反してはいるが Hibernate では合法、とも言えないでしょう。たまたま上手く動いているだけ、とみなすのが正しい認識かと考えます。

こちらの動画でも似たような話題が挙がっていました: