問題
-
reposytoryに主キーでdeleteメソッドを送っても、当該レコードが削除されないらしく、再表示用のhdr検索で、dtlが検索されてしまう
-
以下のようなentityをもつ
-
dtlEntityは子データ(明細)
-
hdrEntityが親
-
hdrEntityは、以下のようにリストフィールドにdtlEntityを持つ
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "tMitsumoriHdrEntity")
@JsonIgnore
private List<DtlEntity> dtlEntity;
- コントローラ上で、dtlEntityをリポジトリのdeleteメソッドで削除を行うが、画面上では消えたように見えるが、画面を別のリクエスト後に生き返る、永続化がうまくできていないらしい
前提
- Spring-boot 3.7.1
- Spring Tool Suite Version: 3.7.1.RELEASE
- java
対策
1. 関連Entityの直接削除は行わない
- 関連を持つ場合、直接削除するとhdrの方にデータが残ってしまい、削除が戻ってしまう
dtlRepository.delete(dtlEntity);
- だけだると、HdrEntityの方にまだそのdtlEntityが残ってしまっていて、消えない
2. orphanRemovealをtrueにする
- oneToManyに、orphanRemoval=true属性をつけないと、関連テーブルを削除してもメモリ上だけで、永続化がされない
// 明細テーブル
@OneToMany(cascade = CascadeType.ALL, orphanRemoval=true, fetch = FetchType.EAGER, mappedBy = "tMitsumoriHdrEntity")
@JsonIgnore
private List<DtlEntity> dtlEntity;
3. A collection with cascade="all-delete-orphan" was no longer referencedエラーの対処
-
リストで関連entityをフィールドで持つとき、clearメソッドで関連づけをクリアしてaddして入れ直す、という方法で永続化を行わなければならない
-
NG例
HdrEntity.setDtlEntity(saveDtlList);
HdRepository.save(HdrEntity);
- リストの項目数が変わる変更を行うとき、
- 消したいEntityをremove後のリストをフィールドに代入し、
- リポジトリのsaveで永続化を行なった場合
A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance
-
エラーが発生する
-
正しい
HdrEntity.getDtlEntity().clear();
HdrEntity.getDtlEntity().addAll(saveDtlList);
HdRepository.save(HdrEntity);
- 先に、Entityのリストが入るフィールドをclear()し、
- もう一度そのフィールドに変更後のリストを入れ直す
参考
HibernateException - A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance
http://cristian.sulea.net/blog.php?p=2014-06-28-hibernate-exception-a-collection-with-cascade-all-delete-orphan-was-no-longer-referenced-by-the-owning-entity-instance
5.2. データベースアクセス(JPA編
5.2.2.11. Entityの削除処理の実装
https://terasolunaorg.github.io/guideline/public_review/ArchitectureInDetail/DataAccessJpa.html#id38
JPAについて調べてみた
http://juzow.hatenablog.com/entry/20121017/1350480972