LoginSignup
8
14

More than 5 years have passed since last update.

OneToManyのリストフィールドの削除・更新の仕方

Last updated at Posted at 2017-08-27

問題

  • reposytoryに主キーでdeleteメソッドを送っても、当該レコードが削除されないらしく、再表示用のhdr検索で、dtlが検索されてしまう

  • 以下のようなentityをもつ

  • dtlEntityは子データ(明細)

  • hdrEntityが親

- hdrEntityは、以下のようにリストフィールドにdtlEntityを持つ

HdrEntity
@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

8
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
14