home wiki.fukuchiharuki.me
Menu

キーワード

  • JPA
  • Spring Boot
  • Kotlin

目次

したいこと

ひとまず最小で基本的な関連と永続化処理を実装したい。

単独のエンティティ

まずはただIDで識別できる単独の実体。

モデル

@Entity
@Table
class Foo(
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  var id: Long = -1,

  var name: String = ""
)

エンティティにはIDが必要

JPAのエンティティはID(プライマリキー)を持つ、のが基本。

永続化処理

val entity = Foo(name = "フー")
entityManager.persist(entity)

Kotlinで実装する場合デフォルト値の定義が必要

Kotlinでエンティティを実装する場合、デフォルト値を定義しておく必要がある。デフォルト値を定義しておかないと、エンティティ永続化時にエラーが発生する。永続化時に値があるかどうかではないことに注意。エラーメッセージからだと原因がなんとも想像つかない。

detached entity passed to persist spring jpa

1対多(集約等)の関係

伝票・明細の関係。伝票単位で一式保存するものとして。

モデル

Fooが伝票、Barが明細。

@Entity
@Table
class Foo(
  @OneToMany(mappedBy = "foo", cascade = [CascadeType.ALL], orphanRemoval = true)
  var barList: MutableList<Bar> = emptyList<Bar>().toMutableList()

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  var id: Long = -1,

  var name: String = "",

  @Version
  var version: Long = -1
)
@Entity
@Table
class Bar(
  @ManyToOne
  @JoinColumn(name = "foo_id", referencedColumnName = "id")
  var foo: Foo? = null,

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  var id: Long = -1,

  var name: String = ""
)

@OneToManyの設定

mappedBy
伝票側エンティティが明細側のエンティティから何として関連しているか
cascade
明細側エンティティにカスケードする永続化オペレーション
orphanRemoval
リレーションから削除した明細側エンティティに削除操作を適用する

@ManyToOneの設定

name
伝票側エンティティを指定する明細側のエンティティ上の外部キー
referencedColumnName
その外部キーに該当する伝票側エンティティの主キー

伝票側に@Version

伝票側エンティティに楽観ロック用のバージョンを設ける。

永続化処理

val entity = Foo(name = "フー")
  .apply {
    barList.add(
      Bar(foo = this, name = "バー")
    )
  }
entityManager.persist(entity)

明細側エンティティの永続化処理は不要

永続化オペレーションをカスケードするのでpersistするのは伝票側エンティティだけでいい。

多対1(イベント等)の関係

TBC

多対多(関連テーブル)の関係

TBC

1対1(カーソル等)の関係

TBC

参考