- 履歴一覧
- 現在との差分 を表示
- ソース を表示
- 履歴 を表示
- Spring Boot/Data JPA/エンティティを実装する へ行く。
- 1 (2023-01-12 (木) 16:47:58)
- 2 (2023-01-12 (木) 19:03:11)
- 3 (2023-01-17 (火) 19:37:09)
- 4 (2023-01-27 (金) 12:11:59)
- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2023-01-12T10:03:11+00:00","default:haruki","haruki") #author("2023-01-17T10:37:09+00:00","default:haruki","haruki") * キーワード [#hc7c5f18] - JPA - Spring Boot - Kotlin * 目次 [#u3ea0b4d] #contents * したいこと [#ya88d2e3] ひとまず最小で基本的な関連と永続化処理を実装したい。 * 単独のエンティティ [#u812d77a] * エンティティ(単体) [#u812d77a] まずはただIDで識別できる単独の実体。 ** モデル [#dda697ef] @Entity @Table class Foo( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long = -1, var name: String = "" ) *** エンティティにはIDが必要 [#c49b023b] JPAのエンティティはID(プライマリキー)を持つ、のが基本。 ** 永続化処理 [#tf12ecc5] val entity = Foo(name = "フー") entityManager.persist(entity) *** Kotlinで実装する場合デフォルト値の定義が必要 [#l1e04d92] Kotlinでエンティティを実装する場合、デフォルト値を定義しておく必要がある。デフォルト値を定義しておかないと、エンティティ永続化時にエラーが発生する。永続化時に値があるかどうかではないことに注意。エラーメッセージからだと原因がなんとも想像つかない。 detached entity passed to persist spring jpa * 1対多(集約等)の関係 [#g2c10fb2] * 集約等(1対多)の関係 [#g2c10fb2] 伝票・明細の関係。伝票単位で一式保存するものとして。 ** モデル [#x0512dff] 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の設定 [#e05bb408] : mappedBy | 伝票側エンティティが明細側のエンティティから何として関連しているか : mappedBy | 伝票側エンティティが明細側エンティティから何として関連しているか : cascade | 明細側エンティティにカスケードする永続化オペレーション : orphanRemoval | リレーションから削除した明細側エンティティに削除操作を適用する *** @ManyToOneの設定 [#y0268b0d] : name | 伝票側エンティティを指定する明細側のエンティティ上の外部キー : name | 伝票側エンティティを指定する明細側エンティティ上の外部キー : referencedColumnName | その外部キーに該当する伝票側エンティティの主キー *** 伝票側に@Version [#tf9cd8f0] 伝票側エンティティに楽観ロック用のバージョンを設ける。 ** 永続化処理 [#y27fae2b] val entity = Foo(name = "フー") .apply { barList.add( Bar(foo = this, name = "バー") ) } entityManager.persist(entity) *** 明細側エンティティの永続化処理は不要 [#vb186a99] 永続化オペレーションをカスケードするのでpersistするのは伝票側エンティティだけでいい。 * 多対1(イベント等)の関係 [#w9a9673b] * ログやイベント等(多対1)の関係 [#w9a9673b] TBC 親エンティティに紐づくログやイベント等の関係。親側エンティティの単位で子側エンティティ(ログやイベント等)を一括保存しない。 * 多対多(関連テーブル)の関係 [#nb058329] ** モデル [#b1701098] @Entity @Table class Foo( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long = -1 ) @Entity @Table class FooEvent( @ManyToOne @JoinColumn(name = "foo_id", referencedColumnName = "id") var foo: Foo? = null, @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long = -1 ) *** @ManyToOneの設定 [#r7579c63] 1対多(集約等)の関係、明細側のエンティティと同じ。 : name | 親側エンティティを指定する子側エンティティ上の外部キー : referencedColumnName | その外部キーに該当する伝票側エンティティの主キー ** 永続化処理 [#xe866e76] entityManager.find(Foo::class.java, fooId) ?.let { val entity = FooEvent(foo = it) entityManager.persist(entity) entity // ^let } *** managedな親側エンティティが必要 [#f8f37fe5] 子側エンティティにセットする親側エンティティはmanagedである必要がある(はず)。 * カーソル等(1対1)の関係 [#k9483d82] TBC * 1対1(カーソル等)の関係 [#k9483d82] * 任意の関連をもつ(1対0,1)の関係 [#nb058329] TBC * 参考 [#sf4400b4] - [[java - How to use spring Repository without @Id? - Stack Overflow:https://stackoverflow.com/a/29561919]] - [[エンティティの状態遷移:http://itdoc.hitachi.co.jp/manuals/link/cosmi_v0870/APKC/EU070301.HTM]] - [[@OneToMany:http://itdoc.hitachi.co.jp/manuals/link/cosmi_v0870/APR4/EU260088.HTM]] - [[OneToMany (Jakarta EE 仕様 API) - Javadoc:https://spring.pleiades.io/specifications/platform/8/apidocs/javax/persistence/onetomany]] - [[OneToManyのリストフィールドの削除・更新の仕方 - Qiita:https://qiita.com/yukihigasi/items/14eac33cc2043fcdbddb]]